CiscsoPonce commited on
Commit
bfab9f9
·
1 Parent(s): b329f6a

docs: update README for Sprint 9 — debate, Alpaca, catalyst, evaluators

Browse files

- Add multi-agent debate architecture section
- Add Alpaca paper trading module docs
- Add catalyst polling daemon docs
- Add grading engine / evaluators docs
- Update project structure tree with all new files
- Update configuration section with new env vars
- Update LangGraph features table with subgraph

Made-with: Cursor

Files changed (1) hide show
  1. README.md +90 -15
README.md CHANGED
@@ -10,13 +10,13 @@ app_port: 7860
10
 
11
  # PrimoGreedy Agent
12
 
13
- **PrimoGreedy** is an automated, AI-driven financial analysis agent designed to hunt, filter, and evaluate Micro-Cap and Small-Cap stocks. It acts as a ruthless "Logic Firewall," aggressively rejecting high-debt, cash-burning, and overvalued companies before deploying a ReAct (Reasoning and Acting) LLM to write highly structured fundamental investment memos.
14
 
15
  ---
16
 
17
  ## Core Architecture (The LangGraph Engine)
18
 
19
- The system is built on **LangGraph** following modern best practices (partial state updates, `Command` routing, `Send` parallel fan-out, checkpointing, and `RetryPolicy`).
20
 
21
  ### Hunter Pipeline (`src/agent.py` / `src/whale_hunter.py`)
22
 
@@ -32,7 +32,11 @@ START --> initial_routing --> [chat] --> END
32
  - Share Price: under $30.00
33
  - Zombie Filter: rejects unprofitable companies with < 6 months cash runway
34
  - Routes directly to `analyst` (PASS / retries exhausted) or back to `scout` (FAIL) via `Command`.
35
- 3. **Analyst Node** — Senior Broker analysis powered by OpenRouter (5-model fallback chain). Calls Finnhub tools for deep fundamentals and insider sentiment. Fetches **SEC EDGAR** 10-K/10-Q filings for US equities (MD&A + Risk Factors ground truth). Returns structured `InvestmentVerdict` (Pydantic model) with guaranteed `STRONG BUY | BUY | WATCH | AVOID` verdicts plus **Kelly Criterion position sizing**, falling back to plain LLM output.
 
 
 
 
36
 
37
  ### Workflow Pipeline (`src/workflows/workflow.py`)
38
 
@@ -42,6 +46,20 @@ START --> [data_collection] --> [technical_analysis] --> [news_intelligence] -->
42
 
43
  A linear 4-node pipeline for deep single-ticker analysis (used by `main.py` CLI).
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  ### Parallel Region Orchestrator (`src/whale_hunter.py`)
46
 
47
  The daily cron dispatches all 4 markets (USA, UK, Canada, Australia) **in parallel** via the LangGraph `Send` API:
@@ -55,6 +73,8 @@ START --> dispatch_regions --> [hunt_region: USA] \
55
 
56
  Each `hunt_region` invokes the full per-region subgraph (scout -> gatekeeper -> analyst -> email).
57
 
 
 
58
  ---
59
 
60
  ## LangGraph Features Used
@@ -69,6 +89,7 @@ Each `hunt_region` invokes the full per-region subgraph (scout -> gatekeeper ->
69
  | `RetryPolicy` | All nodes | `max_attempts=3, initial_interval=2.0` for transient errors |
70
  | `recursion_limit` | All `invoke()` calls | Set to 30 to prevent infinite loops |
71
  | Structured output | Analyst nodes | `with_structured_output(InvestmentVerdict)` for validated verdicts |
 
72
  | `@tool` decorator | `sec_edgar.py`, `finance_tools.py` | LangChain tool pattern for API integrations |
73
  | `START` / `END` | All graphs | Modern entry-point API (no deprecated `set_entry_point`) |
74
 
@@ -87,14 +108,41 @@ A Chainlit-powered chat interface.
87
  ### The Morning Cron (`src/whale_hunter.py`)
88
  Headless agent running as a **GitHub Action** daily cron. Hunts all 4 regions in parallel, evaluates candidates through the full pipeline, and emails HTML reports via Resend.
89
 
 
 
 
 
 
 
 
 
90
  ### VPS Data Layer (`vps/`)
91
  Optional **FastAPI + DuckDB** backend deployed on a VPS (behind Tailscale) that replaces local JSON files for persistence:
92
  - `seen_tickers` — Prevents re-analysing the same ticker within 30 days
93
- - `paper_portfolio` — Records all BUY/STRONG BUY/WATCH paper trades with Kelly position sizing
94
  - `agent_runs` — Operational metrics for LangSmith correlation
95
 
96
  The agent (`src/core/memory.py`, `src/portfolio_tracker.py`) auto-detects the VPS via `VPS_API_URL` env var and falls back to local JSON files when unavailable.
97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  ### SEC EDGAR Ground Truth (`src/sec_edgar.py`)
99
  Fetches the most recent 10-K or 10-Q filing from SEC EDGAR for US equities and extracts two investment-critical sections:
100
  - **Item 7: Management's Discussion & Analysis (MD&A)** — Management's own view of operations
@@ -135,7 +183,7 @@ pip install -r requirements.txt
135
 
136
  ### 2. Configuration (`.env`)
137
  ```env
138
- OPENROUTER_API_KEY=your_key # LLM Inference (5-model fallback chain)
139
  FINNHUB_API_KEY=your_key # Deep Fundamentals & Insider Data
140
  BRAVE_API_KEY=your_key # Web Search
141
  RESEND_API_KEY_CISCO=your_key # Email Reporting (Cron only)
@@ -143,6 +191,19 @@ RESEND_API_KEY_CISCO=your_key # Email Reporting (Cron only)
143
  # Optional: VPS Data API
144
  VPS_API_URL=http://your-vps:8080
145
  VPS_API_KEY=your_vps_key
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  ```
147
 
148
  ### 3. Launching the UI
@@ -160,6 +221,12 @@ python3 main.py
160
  bash vps/deploy.sh
161
  ```
162
 
 
 
 
 
 
 
163
  ---
164
 
165
  ## Project Structure
@@ -172,25 +239,28 @@ primogreedy/
172
  ├── src/
173
  │ ├── agent.py # Interactive Chainlit pipeline (scout/gatekeeper/analyst)
174
  │ ├── whale_hunter.py # Daily cron pipeline + parallel Send orchestrator
175
- │ ├── llm.py # OpenRouter LLM with 5-model fallback chain
176
  │ ├── sec_edgar.py # SEC EDGAR 10-K/10-Q filing fetcher + parser (@tool)
177
  │ ├── finance_tools.py # Finnhub tools (@tool decorated)
178
- │ ├── portfolio_tracker.py # Paper trade recording + evaluation (with position_size)
179
  │ ├── email_utils.py # Resend email dispatch
180
  │ ├── core/
181
- │ │ ├── state.py # AgentState (TypedDict with Annotated reducers)
182
  │ │ ├── memory.py # Seen-tickers ledger (VPS or local JSON)
183
- │ │ ├── search.py # Brave Search wrapper
184
- │ │ ├── ticker_utils.py # Ticker extraction, suffix resolution
185
  │ │ └── logger.py # Logging config
186
  │ ├── models/
187
- │ │ ├── verdict.py # InvestmentVerdict Pydantic model (with Kelly fields)
188
- │ │ └── kelly.py # Kelly Criterion position sizing calculator
189
- │ ├── agents/ # Workflow pipeline nodes
 
190
  │ │ ├── data_collection_agent.py
191
  │ │ ├── technical_analysis_agent.py
192
  │ │ ├── news_intelligence_agent.py
193
  │ │ └── portfolio_manager_agent.py
 
 
194
  │ ├── workflows/
195
  │ │ ├── workflow.py # 4-node linear workflow graph
196
  │ │ └── state.py # Workflow-specific AgentState
@@ -200,13 +270,18 @@ primogreedy/
200
  │ │ └── insider_feed.py # SEC EDGAR / Finnhub insider data
201
  │ └── prompts/
202
  │ └── senior_broker.py # LangSmith Hub prompt template
 
 
 
 
203
  ├── vps/
204
- │ ├── api.py # FastAPI + DuckDB data API
 
205
  │ ├── schema.sql # DuckDB table definitions
206
  │ ├── deploy.sh # VPS deployment script
207
  │ └── requirements.txt # VPS-specific dependencies
208
  └── .github/workflows/
209
- └── hunter.yml # Daily cron GitHub Action
210
  ```
211
 
212
  ---
 
10
 
11
  # PrimoGreedy Agent
12
 
13
+ **PrimoGreedy** is an automated, AI-driven financial analysis agent designed to hunt, filter, and evaluate Micro-Cap and Small-Cap stocks. It acts as a ruthless "Logic Firewall," aggressively rejecting high-debt, cash-burning, and overvalued companies before deploying a multi-agent LLM pipeline to write highly structured fundamental investment memos — and optionally execute paper trades via Alpaca.
14
 
15
  ---
16
 
17
  ## Core Architecture (The LangGraph Engine)
18
 
19
+ The system is built on **LangGraph** following modern best practices (partial state updates, `Command` routing, `Send` parallel fan-out, checkpointing, `RetryPolicy`, and multi-agent subgraphs).
20
 
21
  ### Hunter Pipeline (`src/agent.py` / `src/whale_hunter.py`)
22
 
 
32
  - Share Price: under $30.00
33
  - Zombie Filter: rejects unprofitable companies with < 6 months cash runway
34
  - Routes directly to `analyst` (PASS / retries exhausted) or back to `scout` (FAIL) via `Command`.
35
+ 3. **Analyst Node** — Two modes controlled by `USE_DEBATE` env var:
36
+ - **Single-LLM** (default): Senior Broker analysis via OpenRouter (6-model fallback chain) with structured `InvestmentVerdict` output.
37
+ - **Multi-Agent Debate** (`USE_DEBATE=true`): Three-agent Investment Committee subgraph (Pitcher → Skeptic → Judge) that produces a hallucination-resistant verdict.
38
+
39
+ Both modes fetch **SEC EDGAR** 10-K/10-Q filings (US equities), call Finnhub tools for deep fundamentals, and compute **Kelly Criterion position sizing**.
40
 
41
  ### Workflow Pipeline (`src/workflows/workflow.py`)
42
 
 
46
 
47
  A linear 4-node pipeline for deep single-ticker analysis (used by `main.py` CLI).
48
 
49
+ ### Multi-Agent Debate (`src/agents/debate.py`)
50
+
51
+ When `USE_DEBATE=true`, the analyst node runs a 3-agent LangGraph subgraph:
52
+
53
+ ```
54
+ START --> [pitcher (Gemma)] --> [skeptic (Mistral)] --> [judge (Nemotron)] --> END
55
+ ```
56
+
57
+ 1. **The Pitcher** — Writes the strongest bullish thesis using only provided data.
58
+ 2. **The Skeptic** — Challenges the bull case, flagging any fabricated claims.
59
+ 3. **The Judge** — Synthesises the debate into a structured `InvestmentVerdict`, downgrading if fabrications were found.
60
+
61
+ Models are configurable via `DEBATE_PITCHER_MODEL`, `DEBATE_SKEPTIC_MODEL`, `DEBATE_JUDGE_MODEL` env vars.
62
+
63
  ### Parallel Region Orchestrator (`src/whale_hunter.py`)
64
 
65
  The daily cron dispatches all 4 markets (USA, UK, Canada, Australia) **in parallel** via the LangGraph `Send` API:
 
73
 
74
  Each `hunt_region` invokes the full per-region subgraph (scout -> gatekeeper -> analyst -> email).
75
 
76
+ Supports **catalyst-triggered single-ticker mode** via `CATALYST_TICKER` env var (used by `repository_dispatch` from the VPS polling daemon).
77
+
78
  ---
79
 
80
  ## LangGraph Features Used
 
89
  | `RetryPolicy` | All nodes | `max_attempts=3, initial_interval=2.0` for transient errors |
90
  | `recursion_limit` | All `invoke()` calls | Set to 30 to prevent infinite loops |
91
  | Structured output | Analyst nodes | `with_structured_output(InvestmentVerdict)` for validated verdicts |
92
+ | Subgraph | `src/agents/debate.py` | Pitcher/Skeptic/Judge multi-agent debate as nested graph |
93
  | `@tool` decorator | `sec_edgar.py`, `finance_tools.py` | LangChain tool pattern for API integrations |
94
  | `START` / `END` | All graphs | Modern entry-point API (no deprecated `set_entry_point`) |
95
 
 
108
  ### The Morning Cron (`src/whale_hunter.py`)
109
  Headless agent running as a **GitHub Action** daily cron. Hunts all 4 regions in parallel, evaluates candidates through the full pipeline, and emails HTML reports via Resend.
110
 
111
+ ### Alpaca Paper Trading (`src/broker/alpaca.py`)
112
+ Optional **Alpaca Markets** integration for live paper trading of US equities:
113
+ - Automatically submits market orders for **BUY / STRONG BUY** verdicts on US tickers
114
+ - Calculates share quantity from Kelly position sizing and account equity
115
+ - Safety limits: minimum $1 order, maximum 25% of equity per position
116
+ - Records `order_id`, `fill_price`, and `broker_status` to VPS
117
+ - Dry-run mode when `ALPACA_ENABLED` is not set (logs but doesn't submit)
118
+
119
  ### VPS Data Layer (`vps/`)
120
  Optional **FastAPI + DuckDB** backend deployed on a VPS (behind Tailscale) that replaces local JSON files for persistence:
121
  - `seen_tickers` — Prevents re-analysing the same ticker within 30 days
122
+ - `paper_portfolio` — Records all paper trades with Kelly sizing, Alpaca order IDs, and fill prices
123
  - `agent_runs` — Operational metrics for LangSmith correlation
124
 
125
  The agent (`src/core/memory.py`, `src/portfolio_tracker.py`) auto-detects the VPS via `VPS_API_URL` env var and falls back to local JSON files when unavailable.
126
 
127
+ ### Catalyst Polling Daemon (`vps/catalyst_poll.py`)
128
+ VPS-based systemd timer that polls every 15 minutes during US market hours for intraday triggers:
129
+ - **Volume spike** — Current volume > 3x average daily volume
130
+ - **Price move** — Intraday move > 10%
131
+ - **Insider filing** — New SEC Form 4 purchase for a tracked ticker
132
+
133
+ When triggered, fires a GitHub Actions `repository_dispatch` event to run the pipeline for that specific ticker.
134
+
135
+ ### Grading Engine (`scripts/`)
136
+ Automated quality assurance via LangSmith Evaluators:
137
+ - `scripts/build_golden_dataset.py` — Curates 50 representative traces into a LangSmith Dataset
138
+ - `scripts/evaluators.py` — 5 custom evaluators:
139
+ - **Catalyst Grounding** (LLM-as-a-Judge) — Scores whether claims are backed by data
140
+ - **Company Identity** (LLM-as-a-Judge) — Catches "name-trap" hallucinations
141
+ - **Format** — Validates headers, no duplicates, Kelly present for BUY
142
+ - **Verdict Validity** — Ensures verdict is one of the 4 valid values
143
+ - **Kelly Math** — Checks allocation is within [1%, 25%] bounds
144
+ - `scripts/run_evals.py` — Runs all evaluators against the golden dataset
145
+
146
  ### SEC EDGAR Ground Truth (`src/sec_edgar.py`)
147
  Fetches the most recent 10-K or 10-Q filing from SEC EDGAR for US equities and extracts two investment-critical sections:
148
  - **Item 7: Management's Discussion & Analysis (MD&A)** — Management's own view of operations
 
183
 
184
  ### 2. Configuration (`.env`)
185
  ```env
186
+ OPENROUTER_API_KEY=your_key # LLM Inference (6-model fallback chain)
187
  FINNHUB_API_KEY=your_key # Deep Fundamentals & Insider Data
188
  BRAVE_API_KEY=your_key # Web Search
189
  RESEND_API_KEY_CISCO=your_key # Email Reporting (Cron only)
 
191
  # Optional: VPS Data API
192
  VPS_API_URL=http://your-vps:8080
193
  VPS_API_KEY=your_vps_key
194
+
195
+ # Optional: Alpaca Paper Trading (US equities only)
196
+ ALPACA_API_KEY=your_key
197
+ ALPACA_SECRET_KEY=your_secret
198
+ ALPACA_ENABLED=true
199
+
200
+ # Optional: Multi-Agent Debate
201
+ USE_DEBATE=true # Enable pitcher/skeptic/judge pipeline
202
+
203
+ # Optional: LangSmith Observability
204
+ LANGCHAIN_TRACING_V2=true
205
+ LANGCHAIN_API_KEY=your_key
206
+ LANGCHAIN_PROJECT=primogreedy
207
  ```
208
 
209
  ### 3. Launching the UI
 
221
  bash vps/deploy.sh
222
  ```
223
 
224
+ ### 6. Running Evaluations (optional)
225
+ ```bash
226
+ python scripts/build_golden_dataset.py # Build the golden dataset from LangSmith
227
+ python scripts/run_evals.py # Run all evaluators
228
+ ```
229
+
230
  ---
231
 
232
  ## Project Structure
 
239
  ├── src/
240
  │ ├── agent.py # Interactive Chainlit pipeline (scout/gatekeeper/analyst)
241
  │ ├── whale_hunter.py # Daily cron pipeline + parallel Send orchestrator
242
+ │ ├── llm.py # OpenRouter LLM with 6-model fallback + structured output
243
  │ ├── sec_edgar.py # SEC EDGAR 10-K/10-Q filing fetcher + parser (@tool)
244
  │ ├── finance_tools.py # Finnhub tools (@tool decorated)
245
+ │ ├── portfolio_tracker.py # Paper trade recording + Alpaca execution
246
  │ ├── email_utils.py # Resend email dispatch
247
  │ ├── core/
248
+ │ │ ├── state.py # AgentState (TypedDict with Annotated reducers + debate fields)
249
  │ │ ├── memory.py # Seen-tickers ledger (VPS or local JSON)
250
+ │ │ ├── search.py # Brave Search wrapper (with retry/backoff)
251
+ │ │ ├── ticker_utils.py # Ticker extraction, suffix resolution, noise filtering
252
  │ │ └── logger.py # Logging config
253
  │ ├── models/
254
+ │ │ ├── verdict.py # InvestmentVerdict Pydantic model (with header-stripping)
255
+ │ │ └── kelly.py # Kelly Criterion position sizing (with 10-min cache)
256
+ │ ├── agents/
257
+ │ │ ├── debate.py # Multi-agent pitcher/skeptic/judge subgraph
258
  │ │ ├── data_collection_agent.py
259
  │ │ ├── technical_analysis_agent.py
260
  │ │ ├── news_intelligence_agent.py
261
  │ │ └── portfolio_manager_agent.py
262
+ │ ├── broker/
263
+ │ │ └── alpaca.py # Alpaca Paper Trading order router + execution
264
  │ ├── workflows/
265
  │ │ ├── workflow.py # 4-node linear workflow graph
266
  │ │ └── state.py # Workflow-specific AgentState
 
270
  │ │ └── insider_feed.py # SEC EDGAR / Finnhub insider data
271
  │ └── prompts/
272
  │ └── senior_broker.py # LangSmith Hub prompt template
273
+ ├── scripts/
274
+ │ ├── build_golden_dataset.py # LangSmith golden dataset builder
275
+ │ ├── evaluators.py # Custom LangSmith evaluators (5 scorers)
276
+ │ └── run_evals.py # Evaluation runner
277
  ├── vps/
278
+ │ ├── api.py # FastAPI + DuckDB data API (with broker fields)
279
+ │ ├── catalyst_poll.py # Intraday catalyst polling daemon
280
  │ ├── schema.sql # DuckDB table definitions
281
  │ ├── deploy.sh # VPS deployment script
282
  │ └── requirements.txt # VPS-specific dependencies
283
  └── .github/workflows/
284
+ └── hunter.yml # Daily cron + catalyst dispatch GitHub Action
285
  ```
286
 
287
  ---