Commit Graph

96 Commits

Author SHA1 Message Date
ahmet guzererler 86a0f5d9b7
Merge pull request #59 from aguzererler/testing/industry-deep-dive-parsing-12762969703991793840
🧪 test: add tests and parsing logic for text formats in _extract_top_sectors
2026-03-21 17:34:47 +01:00
ahmet guzererler a42676d8b6
Merge pull request #57 from aguzererler/remove-unused-imports-alpha-vantage-5385473624944698804
🧹 [Code Health] Remove unused imports in alpha_vantage.py
2026-03-21 17:33:57 +01:00
ahmet guzererler ae83ce74fa
Merge pull request #55 from aguzererler/fix/refactor-alpha-vantage-indicator-4324081028548110342
🧹 Refactor long `get_indicator` function to improve maintainability
2026-03-21 17:32:31 +01:00
ahmet guzererler cce5755b30
Merge pull request #62 from aguzererler/test-stockstats-utils-15966200471023157106
🧪 [testing improvement] Add unit tests for _clean_dataframe in stockstats_utils
2026-03-21 17:29:41 +01:00
ahmet guzererler 4747d98cb3
Merge pull request #63 from aguzererler/fix/macro-regime-refactor-299016324797440021
🧹 Refactor classify_macro_regime to improve readability
2026-03-21 17:29:23 +01:00
ahmet guzererler e5be3f4676
Merge pull request #64 from aguzererler/perf/lazy-load-portfolio-snapshot-8090947574151242031
 [performance] Lazy Load JSON Parsing for PortfolioSnapshot Holdings
2026-03-21 17:28:43 +01:00
ahmet guzererler b0424a36d7
Merge pull request #66 from aguzererler/jules-17548469684748509551-99819dec
🧪 [Fix Finnhub API error handling and add coverage]
2026-03-21 17:27:49 +01:00
ahmet guzererler e292c833ce
Merge pull request #48 from aguzererler/fix/unused-typing-imports-8765363568869734056
🧹 Remove unused imports in trading_graph.py
2026-03-21 17:24:14 +01:00
ahmet guzererler 319feac087
Merge pull request #65 from aguzererler/testing-macro-regime-edge-cases-7674628334263228754
🧪 Fix VIX trend logic and add extensive tests for macro regime short history edge cases
2026-03-21 17:23:38 +01:00
ahmet guzererler e877f298bb
Merge pull request #46 from aguzererler/fix-unused-import-finnhub-scanner-619852487739765853
🧹 remove unused import _make_api_request from finnhub_scanner.py
2026-03-21 17:20:03 +01:00
ahmet guzererler 5d600480ce
Merge pull request #45 from aguzererler/code-health/risk-manager-unused-import-1634631888147245992
🧹 Remove unused imports and variables in risk manager
2026-03-21 17:18:31 +01:00
google-labs-jules[bot] bdaf188b33 Fix Finnhub API error handling and add coverage
Extracted the API request logic in `finnhub_news.py` to a private `_fetch_company_news_data` helper to properly catch `Exception` and return an empty list without violating the `str` return type of the main `get_company_news` function. Explicitly allows `ThirdPartyTimeoutError` to propagate to preserve timeout behavior.

Added corresponding tests to mock generic API exceptions and invalid response types. Retained the test verifying fallback behavior for invalid numeric values within `get_insider_transactions`.

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 14:51:29 +00:00
google-labs-jules[bot] 177d35ede5 🧪 Fix VIX trend logic and add extensive tests for macro regime short history edge cases
- Fixed `_signal_vix_trend` to correctly return neutral for insufficient history (`< 21`).
- Added `test_short_history_is_neutral` to `TestSignalVixTrend`.
- Extended coverage for short history and edge cases in `TestSignalCreditSpread`, `TestSignalYieldCurve`, `TestSignalMarketBreadth`, and `TestSignalSectorRotation`.

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 14:48:20 +00:00
google-labs-jules[bot] 7ab7cd7591 perf: lazy load json parsing in PortfolioSnapshot
This commit optimizes `PortfolioSnapshot` instantiation when loaded from the DB or JSON dictionaries by removing the immediate `json.loads(holdings_snapshot)` parsing inside the `from_dict` constructor. Instead, it overrides `__getattribute__` to implement a lazy-loading pattern, where the `holdings_snapshot` string is only parsed into a Python dictionary the very first time the field is accessed.

    This optimization ensures that parsing large JSON payloads doesn't block the instantiation of snapshots, which is particularly beneficial in workflows that load a large historical series of snapshots but never access their `holdings_snapshot` field.

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 08:32:52 +00:00
google-labs-jules[bot] 77694d49c9 Refactor classify_macro_regime into helper functions
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 08:31:07 +00:00
google-labs-jules[bot] a7f5f67f94 🧪 [testing improvement] Add unit tests for _clean_dataframe in stockstats_utils
Added tests to verify the dataframe cleaning logic in stockstats_utils.
Tests cover lowercasing of columns, handling non-string columns, and ensuring original dataframe is not mutated.

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 08:30:52 +00:00
google-labs-jules[bot] 644ce57b9c test: add tests and parsing logic for text formats in _extract_top_sectors
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 08:28:35 +00:00
google-labs-jules[bot] 1129c0cd21 Refactor interface.py to remove unused imports in alpha_vantage.py
The file `tradingagents/dataflows/alpha_vantage.py` previously acted as an aggregator but did not use the imports it defined, leading to linter warnings (ruff). The dependencies in `tradingagents/dataflows/interface.py` were refactored to import directly from the specialized modules instead. This safely allowed removing all unused imports from `alpha_vantage.py`, improving code health and module clarity without affecting functionality.

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 08:27:10 +00:00
google-labs-jules[bot] 0a53060ce9 Refactor `get_indicator` function in `alpha_vantage_indicator.py`
This change refactors the large monolithic `get_indicator` function by extracting large mapping dictionaries out of the function scope as constants and separating API fetching logic and CSV parsing logic into private helper functions. This drastically improves the maintainability and readability of `alpha_vantage_indicator.py` without introducing any behavioral changes.

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 08:26:02 +00:00
google-labs-jules[bot] 369bc02ef5 🧹 Remove unused imports in trading_graph.py
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 08:22:55 +00:00
google-labs-jules[bot] 404edc56b7 🧹 remove unused import _make_api_request from finnhub_scanner.py
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 08:22:49 +00:00
google-labs-jules[bot] 0955568391 refactor: remove unused imports in risk manager
Removed unused `import json` and `import time` from `tradingagents/agents/managers/risk_manager.py` to improve code health and cleanliness. Also removed unused variable `company_name`. Tested to ensure no functionality is affected.

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 08:22:14 +00:00
google-labs-jules[bot] f82a810c3b Remove unused pandas import and clean up finnhub_stock.py
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 08:21:43 +00:00
ahmet guzererler 69e6bee34b
Merge pull request #40 from aguzererler/fix/remove-unused-timedelta-import-16675261317014341937
🧹 Remove unused `timedelta` import in finnhub_indicators.py
2026-03-21 02:56:10 +01:00
google-labs-jules[bot] 5fa0fe3178 🧹 Remove unused `timedelta` import in finnhub_indicators.py
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 01:54:05 +00:00
google-labs-jules[bot] 8bc92344f8 🧹 chore: remove unused json import in research_manager.py
Removed the unused `import json` line from `tradingagents/agents/managers/research_manager.py` to improve code health and maintainability.

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 01:52:39 +00:00
ahmet guzererler 25457930ae
Merge pull request #36 from aguzererler/fix-unused-imports-utils-14929046510086826793
🧹 Remove unused imports in utils.py
2026-03-21 02:39:50 +01:00
ahmet guzererler 279081d3c7
Merge pull request #38 from aguzererler/perf-optimize-json-extraction-regex-3266597981569245080
 Pre-compile regex in JSON extraction utility
2026-03-21 02:36:33 +01:00
google-labs-jules[bot] 646fe40754 perf: pre-compile regex patterns in extract_json util
Compile THINK_PATTERN and FENCE_PATTERN at the module level to improve
the performance of extract_json by avoiding redundant regex compilation
during function calls.

Measured a ~5% performance improvement in an isolated benchmark.
- Baseline: 51.98 us/call
- Optimized: 49.26 us/call

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 01:34:43 +00:00
google-labs-jules[bot] 13e5534043 chore: remove unused imports `os` and `json` from `tradingagents/dataflows/utils.py`
Identified by `ruff check`, these imports were not being used in the module. Removing them improves code health and maintainability.

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-21 01:34:15 +00:00
ahmet guzererler 9d8566f878
Merge branch 'main' into copilot/refactor-agent-workflows-and-risk-metrics 2026-03-21 02:30:18 +01:00
copilot-swe-agent[bot] 96a2c79cb3 Implement Portfolio Manager Phases 2-5: risk evaluation, candidate prioritization, holding reviewer agent, PM decision agent, trade executor, and portfolio graph orchestration
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-20 14:44:22 +00:00
copilot-swe-agent[bot] 066460a501 feat: add portfolio risk metrics module and LangChain agent tools
- tradingagents/portfolio/risk_metrics.py: pure-Python computation of
  Sharpe, Sortino, VaR, max drawdown, beta, sector concentration from
  PortfolioSnapshot NAV history — no LLM, no external dependencies
- tradingagents/portfolio/__init__.py: export compute_risk_metrics
- tradingagents/agents/utils/portfolio_tools.py: 4 LangChain tools
  wrapping Holding.enrich, Portfolio.enrich, ReportStore APIs, and
  compute_risk_metrics so agents can access portfolio data without
  reimplementing computations
- tests/portfolio/test_risk_metrics.py: 48 tests for risk metrics
- tests/unit/test_portfolio_tools.py: 19 tests for portfolio tools
- tests/portfolio/test_repository.py: fix pre-existing import error

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-20 14:42:43 +00:00
copilot-swe-agent[bot] 1444e8438c feat: Portfolio Manager Phases 2-5 — risk evaluation, candidate prioritization, LLM agents, trade executor
- tradingagents/portfolio/risk_evaluator.py: pure-Python risk metrics
  (log returns, Sharpe, Sortino, VaR, max drawdown, beta, sector
  concentration, portfolio/holding aggregation, constraint checking)
- tradingagents/portfolio/candidate_prioritizer.py: conviction × thesis ×
  diversification × held_penalty scoring; sorted candidate ranking
- tradingagents/portfolio/trade_executor.py: executes BUY/SELL decisions
  (SELLs first), pre-flight constraint checks, EOD snapshot
- tradingagents/agents/portfolio/holding_reviewer.py: LLM agent using
  run_tool_loop() — reviews all holdings, outputs HOLD/SELL JSON
- tradingagents/agents/portfolio/pm_decision_agent.py: pure-reasoning LLM
  agent (no tools) — produces structured BUY/SELL/HOLD decision JSON
- tradingagents/portfolio/portfolio_states.py: PortfolioManagerState
  (MessagesState + Annotated _last_value reducers)
- tradingagents/graph/portfolio_setup.py: PortfolioGraphSetup — sequential
  6-node workflow with factory-pattern non-LLM nodes
- tradingagents/graph/portfolio_graph.py: PortfolioGraph — mirrors
  ScannerGraph pattern with mid/deep_think LLM tiers
- tests/portfolio/test_risk_evaluator.py: 28 tests (pure Python)
- tests/portfolio/test_candidate_prioritizer.py: 10 tests (pure Python)
- tests/portfolio/test_trade_executor.py: 10 tests (MagicMock repo)
- tradingagents/portfolio/__init__.py: exports new symbols

All 93 tests pass (4 integration skipped, no regressions).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-20 14:38:48 +00:00
Ahmet Guzererler a17e5f3707 feat: complete portfolio data foundation — psycopg2 client, repository, tests
Replace supabase-py stubs with working psycopg2 implementation using
Supabase pooler connection string. Implement full business logic in
repository (avg cost basis, cash accounting, trade recording, snapshots).
Add 12 unit tests + 4 integration tests (51 total portfolio tests pass).
Fix cash_pct bug in models.py, update docs for psycopg2 + pooler pattern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 14:06:50 +01:00
copilot-swe-agent[bot] aa4dcdeb80 feat: implement Portfolio models, ReportStore, and tests; fix SQL constraint
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-20 11:16:39 +00:00
copilot-swe-agent[bot] 7ea9866d1d docs: ADR-012 — raw supabase-py over Prisma/SQLAlchemy for portfolio data layer
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-20 10:48:40 +00:00
copilot-swe-agent[bot] f1cabe7a4a feat: portfolio manager data foundation — docs, SQL migration, and module scaffolding
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-20 10:40:48 +00:00
Copilot 179e55f264
fix(tests): complete PR #26 — enforce socket isolation in unit tier and add test suite reference doc (#30)
* Initial plan

* fix(tests): complete PR #26 — move integration tests to tests/integration/ and fix 4 failing unit tests

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

* docs: create docs/testing.md — comprehensive test suite reference with 5 Mermaid flowcharts

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-19 17:41:25 +01:00
ahmet guzererler d92fd9cab1
feat: NotebookLM sync with date-specific sources and consolidation (#28) 2026-03-19 15:39:25 +01:00
ahmet guzererler d4fefc804e
feat: daily digest consolidation and Google NotebookLM sync (#23)
* feat: daily digest consolidation and NotebookLM sync

- Add tradingagents/daily_digest.py: appends timestamped entries from
  analyze and scan runs into a single reports/daily/{date}/daily_digest.md
- Add tradingagents/notebook_sync.py: uploads digest to Google NotebookLM
  via nlm CLI, deleting the previous version before uploading (opt-in,
  skips silently if NOTEBOOK_ID is not set)
- Add get_digest_path() helper to report_paths.py
- Hook both analyze and scan CLI commands to append + sync after each run
- Add NOTEBOOK_ID to .env.example

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: update agent memory for daily digest + NotebookLM sync

Update CURRENT_STATE, ARCHITECTURE, and COMPONENTS context files to
reflect the feat/daily-digest-notebooklm implementation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: correct nlm CLI commands and env var name for NotebookLM sync

- Use nlm note list/create/update instead of source list/add/delete
- Parse notes from {"notes": [...]} response structure
- Rename NOTEBOOK_ID -> NOTEBOOKLM_ID in both code and .env.example
- Auto-discover nlm at ~/.local/bin/nlm when not in PATH
- Tested: create on first run, update on subsequent runs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 12:21:03 +01:00
ahmet guzererler a90f14c086
feat: unified report paths, structured observability logging, and memory system update (#22)
* gitignore

* feat: unify report paths under reports/daily/{date}/ hierarchy

All generated artifacts now land under a single reports/ tree:
- reports/daily/{date}/market/ for scan results (was results/macro_scan/)
- reports/daily/{date}/{TICKER}/ for per-ticker analysis (was reports/{TICKER}_{timestamp}/)
- reports/daily/{date}/{TICKER}/eval/ for eval logs (was eval_results/{TICKER}/...)

Adds tradingagents/report_paths.py with centralized path helpers used by
CLI commands, trading graph, and pipeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: structured observability logging for LLM, tool, and vendor calls

Add RunLogger (tradingagents/observability.py) that emits JSON-lines events
for every LLM call (model, agent, tokens in/out, latency), tool invocation
(tool name, args, success, latency), data vendor call (method, vendor,
success/failure, latency), and report save.

Integration points:
- route_to_vendor: log_vendor_call() on every try/catch
- run_tool_loop: log_tool_call() on every tool invoke
- ScannerGraph: new callbacks param, passes RunLogger.callback to all LLM tiers
- pipeline/macro_bridge: picks up RunLogger from thread-local, passes to TradingAgentsGraph
- cli/main.py: one RunLogger per command (analyze/scan/pipeline), write_log()
  at end, summary line printed to console

Log files co-located with reports:
  reports/daily/{date}/{TICKER}/run_log.jsonl   (analyze)
  reports/daily/{date}/market/run_log.jsonl     (scan)
  reports/daily/{date}/run_log.jsonl            (pipeline)

Also fix test_long_response_no_nudge: update "A"*600 → "A"*2100 to match
MIN_REPORT_LENGTH=2000 threshold set in an earlier commit.

Update memory system context files (ARCHITECTURE, COMPONENTS, CONVENTIONS,
GLOSSARY, CURRENT_STATE) to document observability and report path systems.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 09:06:40 +01:00
Copilot 3b6e399563
Resolve merge conflicts after PR #18 merge into main (#19)
* feat: add extract_json() utility for robust LLM JSON parsing

Handles DeepSeek R1 <think> blocks, markdown code fences, and
preamble/postamble text that LLMs wrap around JSON output.
Applied to macro_synthesis, macro_bridge, and CLI scan output.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: opt-in vendor fallback — fail-fast by default (ADR 011)

Silent cross-vendor fallback corrupts signal quality when data contracts
differ (e.g., AV news has sentiment scores yfinance lacks). Only methods
with fungible data contracts (OHLCV, indices, sector/industry perf,
market movers) now get fallback. All others raise immediately.

- Add FALLBACK_ALLOWED whitelist to interface.py
- Rewrite route_to_vendor() with fail-fast/fallback branching
- Improve error messages with method name, vendors tried, and exception chaining
- Add 11 new tests in test_vendor_failfast.py
- Update ADRs 002 (superseded), 008, 010; create ADR 011

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Initial plan

* fix: address PR #18 review findings - type safety, import ordering, EOF newline

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

* fix: add inline comments explaining combined ValueError catch in json_utils.py

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

---------

Co-authored-by: Ahmet Guzererler <guzererler@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-18 14:38:48 +01:00
ahmet guzererler fa8a0d56fb
feat: opt-in vendor fallback — fail-fast by default (#18)
* feat: add extract_json() utility for robust LLM JSON parsing

Handles DeepSeek R1 <think> blocks, markdown code fences, and
preamble/postamble text that LLMs wrap around JSON output.
Applied to macro_synthesis, macro_bridge, and CLI scan output.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: opt-in vendor fallback — fail-fast by default (ADR 011)

Silent cross-vendor fallback corrupts signal quality when data contracts
differ (e.g., AV news has sentiment scores yfinance lacks). Only methods
with fungible data contracts (OHLCV, indices, sector/industry perf,
market movers) now get fallback. All others raise immediately.

- Add FALLBACK_ALLOWED whitelist to interface.py
- Rewrite route_to_vendor() with fail-fast/fallback branching
- Improve error messages with method name, vendors tried, and exception chaining
- Add 11 new tests in test_vendor_failfast.py
- Update ADRs 002 (superseded), 008, 010; create ADR 011

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 14:25:38 +01:00
Ahmet Guzererler 26b6034294 minor update 2026-03-18 12:43:50 +01:00
Copilot d5fb0fdd94
Resolve merge conflicts after PR #16 merge into main (#17)
* Initial plan

* feat: Finnhub integration layer with review fixes — 100 offline tests, vendor routing, evaluation report

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

* review: extract _MAX_ERROR_LEN constant for error message truncation

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

* re-review: fix version downgrade (0.2.0→0.2.1), extract _safe_fmt helper for earnings formatting

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-18 11:38:44 +01:00
ahmet guzererler 26cd4c8b78
feat: Finnhub integration layer, 141 tests, and vendor evaluation report (#16)
* feat: add Finnhub integration layer, tests, and evaluation report

Adds a complete Finnhub data vendor integration as a supplementary
source alongside Alpha Vantage — zero changes to existing functionality.

New dataflow modules:
- finnhub_common.py: exception hierarchy, thread-safe rate limiter (60/min), _make_api_request
- finnhub_stock.py: get_stock_candles, get_quote
- finnhub_fundamentals.py: get_company_profile, get_financial_statements, get_basic_financials
- finnhub_news.py: get_company_news, get_market_news, get_insider_transactions
- finnhub_scanner.py: market movers (S&P 500 basket workaround), indices, sectors, topic news
- finnhub_indicators.py: SMA, EMA, MACD, RSI, BBANDS, ATR via /indicator endpoint
- finnhub.py: facade re-exporting all public functions

New tests:
- test_finnhub_integration.py: 100 offline (mocked HTTP) tests — all passing
- test_finnhub_live_integration.py: 41 live integration tests — skip gracefully when FINNHUB_API_KEY unset

Evaluation report (docs/finnhub_evaluation.md):
- Full coverage matrix vs Alpha Vantage across 5 data categories
- Free tier viability analysis (60 calls/min)
- Unique capabilities: earnings calendar, economic calendar, XBRL as-filed filings
- Recommendation: add as supplementary vendor for calendar data only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: mark paid-tier Finnhub endpoints; update evaluation with live results

Live testing with free-tier key confirmed:
- /quote, /stock/profile2, /stock/metric, /company-news, /news,
  /stock/insider-transactions → all free tier (27 live tests PASS)
- /stock/candle, /financials-reported, /indicator → paid tier HTTP 403
  (14 tests now properly skipped with @pytest.mark.paid_tier)

Also:
- Register 'integration' and 'paid_tier' markers in pyproject.toml
- Update docs/finnhub_evaluation.md with confirmed endpoint availability table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: wire Finnhub into routing layer — insider txns, calendars, fallback

Changes:
- interface.py: Finnhub added as third vendor (alongside yfinance + AV)
  - get_insider_transactions: Finnhub primary (free, + MSPR bonus signal)
  - get_market_indices/sector_performance/topic_news: Finnhub added as option
  - Fallback catch extended: (AlphaVantageError, FinnhubError, ConnectionError, TimeoutError)
  - New calendar_data category with get_earnings_calendar + get_economic_calendar
- finnhub_scanner.py: added get_earnings_calendar_finnhub, get_economic_calendar_finnhub
  (FOMC/CPI/NFP/GDP events + earnings beats — unique, not in AV at any tier)
- finnhub.py: re-exports new calendar functions
- scanner_tools.py: @tool wrappers for get_earnings_calendar, get_economic_calendar
- default_config.py: tool_vendors["get_insider_transactions"]="finnhub",
  calendar_data vendor category defaulting to "finnhub"
- .env.example: FINNHUB_API_KEY documented
- docs/agent/decisions/010-finnhub-vendor-integration.md: ADR for this decision

All 173 offline tests pass. ADR 002 constraints respected throughout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 11:28:43 +01:00
Copilot 9f397fee75
Sync fork with upstream TauricResearch/TradingAgents (v0.2.1) (#12)
* chore: remove unused chainlit dependency (CVE-2026-22218)

* fix: pass debate round config to ConditionalLogic (#361)

* fix: pass max_debate_rounds and max_risk_discuss_rounds config to ConditionalLogic

* use config values

* fix: add explicit UTF-8 encoding to all file open() calls

Prevents UnicodeEncodeError on Windows where the default encoding
(cp1252/gbk) cannot handle Unicode characters in LLM output.

Closes #77, closes #114, closes #126, closes #215, closes #332

* fix: initialize all debate state fields in propagation.py

InvestDebateState was missing bull_history, bear_history, judge_decision.
RiskDebateState was missing aggressive_history, conservative_history,
neutral_history, latest_speaker, judge_decision. This caused KeyError
in _log_state() and reflection, especially with edge-case config values.

* fix: handle comma-separated indicators in get_indicators tool

LLMs (especially smaller models) sometimes pass multiple indicator
names as a single comma-separated string instead of making separate
tool calls. Split and process each individually at the tool boundary.

* fix: add missing console import to cli/utils.py

Seven error-handling paths used console.print() but console was never
imported, causing NameError on invalid user input.

* fix: harden stock data parsing against malformed CSV and NaN values

Add _clean_dataframe() to normalize stock DataFrames before stockstats:
coerce invalid dates/prices, drop rows missing Close, fill price gaps.
Also add on_bad_lines="skip" to all cached CSV reads.

* chore: update model lists, bump to v0.2.1, fix package build

- OpenAI: add GPT-5.4, GPT-5.4 Pro; remove o-series and legacy GPT-4o
- Anthropic: add Claude Opus 4.6, Sonnet 4.6; remove legacy 4.1/4.0/3.x
- Google: add Gemini 3.1 Pro, 3.1 Flash Lite; remove deprecated
  gemini-3-pro-preview and Gemini 2.0 series
- xAI: clean up model list to match current API
- Simplify UnifiedChatOpenAI GPT-5 temperature handling
- Add missing tradingagents/__init__.py (fixes pip install building)

* docs: add v0.2.1 release note to README

* fix: add http_client support for SSL certificate customization

- Add http_client and http_async_client parameters to all LLM clients
- OpenAIClient, GoogleClient, AnthropicClient now support custom httpx clients
- Fixes SSL certificate verification errors on Windows Conda environments
- Users can now pass custom httpx.Client with verify=False or custom certs

Fixes #369

* Initial plan

---------

Co-authored-by: Yijia-Xiao <yijia-xiao@outlook.com>
Co-authored-by: makk9 <117951691+makk9@users.noreply.github.com>
Co-authored-by: 阳虎 <yanghu@yanghudeMacBook-Pro.local>
Co-authored-by: Yijia Xiao <48253104+Yijia-Xiao@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ahmet guzererler <guzererler@gmail.com>
2026-03-18 07:00:37 +01:00
ahmet guzererler 7728f79e8d
feat: medium-term positioning upgrade (debate rounds, TTM, peer comparison, macro regime) (#14)
* docs: add implementation plan for medium-term positioning upgrade

Covers 4 objectives: increased debate rounds, 8-quarter TTM fundamentals,
sector/peer relative performance, and macro regime classification.

https://claude.ai/code/session_01TuPpssTo83whKkNgSu57HH

* feat: medium-term positioning upgrade (debate rounds, TTM, peer comparison, macro regime)

## Changes

### Step 1: Agentic Debate Depth
- Increase `max_debate_rounds` and `max_risk_discuss_rounds` from 1 → 2 in `default_config.py`
- Fix bug in `trading_graph.py`: wire config values into `ConditionalLogic()` (was ignoring config, using hardcoded defaults)

### Step 2: 8-Quarter TTM Fundamental Analysis
- New `tradingagents/dataflows/ttm_analysis.py`: parses quarterly income/balance/cashflow CSV strings, computes TTM (sum of last 4 quarters), QoQ/YoY growth rates, margin trends across 8 quarters
- New `@tool get_ttm_analysis` in `fundamental_data_tools.py`
- Wire into fundamentals ToolNode; register in `TOOLS_CATEGORIES`
- Update fundamentals analyst prompt: "last 8 quarters (2 years)" focus

### Step 3: Sector & Peer Relative Performance
- New `tradingagents/dataflows/peer_comparison.py`: sector peer lookup, 1W/1M/3M/6M/YTD return ranking, alpha vs sector ETF
- New `@tool get_peer_comparison` and `@tool get_sector_relative`
- Wire into fundamentals ToolNode

### Step 4: Macro Regime Flag
- New `tradingagents/dataflows/macro_regime.py`: 6-signal classifier (VIX level/trend, credit spread HYG/LQD, yield curve TLT/SHY, market breadth SPX vs 200-SMA, sector rotation) → risk-on / transition / risk-off
- New `@tool get_macro_regime`; add `macro_regime_report` field to AgentState
- Wire into market ToolNode; feed into research_manager and risk_manager prompts

### Step 5: Tests (88 new unit tests, 0 integration)
- `tests/test_debate_rounds.py` (17 tests)
- `tests/test_ttm_analysis.py` (18 tests)
- `tests/test_peer_comparison.py` (11 tests)
- `tests/test_macro_regime.py` (16 tests)
- `tests/test_config_wiring.py` (12 tests)

All 88 new unit tests pass; no regressions in existing tests.

https://claude.ai/code/session_01TuPpssTo83whKkNgSu57HH

* test: mark live yfinance network tests as integration

TestYfinanceIndustryPerformance, TestRouteToVendorFallback, and TestFallbackRouting
all make live HTTP calls to yfinance (yfinance.Sector / market movers). Mark them
@pytest.mark.integration so they're skipped in standard offline runs.

https://claude.ai/code/session_01TuPpssTo83whKkNgSu57HH

* docs: update memory files for medium-term positioning upgrade

- PROGRESS.md: add milestone section with all new files and changes
- DECISIONS.md: add decisions 008-010 (macro regime, TTM data source, peer comparison)
- MISTAKES.md: add mistakes 10-11 (Python 3.11 f-string, mock data precision)

https://claude.ai/code/session_01TuPpssTo83whKkNgSu57HH

* docs: document git remote setup (origin = aguzererler fork)

origin points to aguzererler/TradingAgents which IS the fork.
No upstream remote configured. All feature branches push to origin.

https://claude.ai/code/session_01TuPpssTo83whKkNgSu57HH

* docs: redirect tracking files to memory system

Replace DECISIONS.md/MISTAKES.md/PROGRESS.md references in CLAUDE.md
with instructions to use /remember memory system. A PreToolUse hook
in ~/.claude/settings.json enforces this by blocking writes to those files.

https://claude.ai/code/session_01TuPpssTo83whKkNgSu57HH

* Initial plan

* Add integration tests for yfinance and Alpha Vantage APIs (78 tests, all passing)

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

* Initial plan

* fix: allow .env variables to override DEFAULT_CONFIG values

Merged origin/main and resolved all 8 conflicting files:
- CLAUDE.md: merged MISTAKES.md ref + Project Tracking section + env override docs
- cli/main.py: kept top-level json import, kept try/except in run_pipeline
- tool_runner.py: kept descriptive comments for MAX_TOOL_ROUNDS
- alpha_vantage_common.py: kept thread-safe rate limiter, robust error handling
- interface.py: kept broader exception catch (AlphaVantageError + ConnectionError + TimeoutError)
- default_config.py: kept _env()/_env_int() env var overrides with load_dotenv() at module level
- scanner_graph.py: kept debug mode fix (stream for debug, invoke for result)
- macro_bridge.py: kept get_running_loop() over deprecated get_event_loop()

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

* fix: move rate limiter sleep outside lock to avoid blocking threads

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

* docs: update PROGRESS, DECISIONS, MISTAKES, CLAUDE with env override implementation

- PROGRESS.md: added env override milestone, updated test count (38 total),
  marked Mistake #9 as resolved, added all new/modified files from PR #9
- DECISIONS.md: added Decision 008 (env var config overrides),
  Decision 009 (thread-safe rate limiter), Decision 010 (broader
  vendor fallback exceptions), updated Decision 007 status to superseded
- MISTAKES.md: updated Mistake #9 status to RESOLVED, added Mistake #10
  (rate limiter held lock during sleep)
- CLAUDE.md: added env var override convention docs, updated critical
  patterns with rate limiter and config fallback key lessons, updated
  mistake count to 10

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

* merge main into branch (-X theirs) and fix tests to pass against current main code

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

* feat: add scanner tests, global demo key in conftest, remove 48 inline key patches

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

* feat: add agentic memory scaffold and migrate tracking files to docs/agent/

Migrate DECISIONS.md, MISTAKES.md, PROGRESS.md, agents/, plans/, and
tradingagents/llm_clients/TODO.md into a structured docs/agent/ scaffold
with ADR-style decisions, plans, templates, and a live state tracker.

This gives agent workflows a standard memory structure for decisions,
plans, logs, and session continuity via CURRENT_STATE.md.

Agent-Ref: docs/agent/plans/global-macro-scanner.md
State-Updated: Yes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: improve Industry Deep Dive report quality with enriched data, sector routing, and tool-call nudge

* Initial plan

* Improve Industry Deep Dive quality: enrich tool data, explicit sector keys, tool-call nudge

- Enrich get_industry_performance_yfinance with 1-day/1-week/1-month price returns
  via batched yf.download() for top 10 tickers (Step 1)
- Add VALID_SECTOR_KEYS, _DISPLAY_TO_KEY, _extract_top_sectors() to industry_deep_dive.py
  to pre-extract top sectors from Phase 1 report and inject them into the prompt (Step 2)
- Add tool-call nudge to run_tool_loop: if first LLM response has no tool calls and is
  under 500 chars, re-prompt with explicit instruction to call tools (Step 3)
- Update scanner_tools.py get_industry_performance docstring to list all valid sector keys (Step 4)
- Add 15 unit tests covering _extract_top_sectors, tool_runner nudge, and enriched output (Step 5)

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

* Address code review: move cols[3] access into try block for IndexError safety

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

* fix: align display row count with download count in get_industry_performance_yfinance

The enriched function downloads price data for top 10 tickers but displayed
20 rows, causing rows 11-20 to show N/A in all price columns. This broke
test_industry_perf_falls_back_to_yfinance which asserts N/A count < 5.
Now both download and display use head(10) for consistency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Co-authored-by: Ahmet Guzererler <guzererler@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* docs: update memory files after PR #13 (Industry Deep Dive quality fix)

- CURRENT_STATE.md: remove Industry Deep Dive blocker (resolved), update
  test count 38 → 53, add PR #13 to Recent Progress, update milestone focus
- decisions/009-industry-deep-dive-quality.md: new ADR documenting the
  three-pronged fix (enriched data, explicit sector routing, tool-call nudge)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: add architecture-coordinator skill for mandatory ADR reading protocol

New Claude Code skill that enforces reading docs/agent/CURRENT_STATE.md,
decisions/, and plans/ before any code changes. Includes conflict resolution
protocol that stops work and quotes the violated ADR rule when user requests
conflict with established architectural decisions.

Files:
- .claude/skills/architecture-coordinator/SKILL.md
- .claude/skills/architecture-coordinator/references/adr-template.md
- .claude/skills/architecture-coordinator/references/reading-checklist.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
2026-03-17 22:27:40 +01:00
Copilot 1362781291
feat: improve Industry Deep Dive report quality with enriched data, sector routing, and tool-call nudge
* Initial plan

* Improve Industry Deep Dive quality: enrich tool data, explicit sector keys, tool-call nudge

- Enrich get_industry_performance_yfinance with 1-day/1-week/1-month price returns
  via batched yf.download() for top 10 tickers (Step 1)
- Add VALID_SECTOR_KEYS, _DISPLAY_TO_KEY, _extract_top_sectors() to industry_deep_dive.py
  to pre-extract top sectors from Phase 1 report and inject them into the prompt (Step 2)
- Add tool-call nudge to run_tool_loop: if first LLM response has no tool calls and is
  under 500 chars, re-prompt with explicit instruction to call tools (Step 3)
- Update scanner_tools.py get_industry_performance docstring to list all valid sector keys (Step 4)
- Add 15 unit tests covering _extract_top_sectors, tool_runner nudge, and enriched output (Step 5)

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

* Address code review: move cols[3] access into try block for IndexError safety

Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>

* fix: align display row count with download count in get_industry_performance_yfinance

The enriched function downloads price data for top 10 tickers but displayed
20 rows, causing rows 11-20 to show N/A in all price columns. This broke
test_industry_perf_falls_back_to_yfinance which asserts N/A count < 5.
Now both download and display use head(10) for consistency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: aguzererler <6199053+aguzererler@users.noreply.github.com>
Co-authored-by: Ahmet Guzererler <guzererler@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 20:10:45 +01:00