Architecture
How the system works under the hood.
System Overview
┌──────────────────────────────────────────────────────────────────────┐
│ CORE ORCHESTRATOR (Durable Object, ~1,400 lines) │
├──────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────┐ ┌──────────────────────────┐ │
│ │ STRATEGY MODULE │ │ POLICY BROKER │ │
│ │ │ │ PolicyEngine.evaluate() │ │
│ │ ┌────────────────────┐ │ └────────────┬─────────────┘ │
│ │ │ Gatherers │ │ │ │
│ │ │ Social, news, SEC │ │ ▼ │
│ │ │ crypto momentum │ │ ┌──────────────┐ │
│ │ └────────┬───────────┘ │ │ Alpaca │ │
│ │ │ │ │ Broker │ │
│ │ ▼ │ └──────────────┘ │
│ │ ┌────────────────────┐ │ │
│ │ │ Prompts │ │ │
│ │ │ LLM templates │ │ │
│ │ └────────┬───────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌────────────────────┐ │ ┌──────────────────────────┐ │
│ │ │ Rules │ │ │ SIGNAL CACHE │ │
│ │ │ Entry, exit, │ │ │ (Persistent) │ │
│ │ │ staleness, options│ │ └──────────────────────────┘ │
│ │ └────────────────────┘ │ │
│ └──────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────┘
The Harness is a thin orchestrator running on Cloudflare Workers with persistent state in Durable Object storage. It delegates data gathering, prompt construction, and trade rules to pluggable strategy modules, routes trade execution through the PolicyBroker, and writes decision rows to D1 with optional R2 snapshots for review. It executes via alarms and cron schedules and survives restarts.
MAHORAGA-Next SENTINEL operates the same agent through authenticated /agent/* endpoints. The MCP server remains available for external tool integrations.
Agent Loop
The agent runs continuously with two main phases:
Data Gathering (24/7)
- Fetch signals from StockTwits, Reddit, SEC EDGAR, GDELT, Alpha Vantage, and crypto momentum
- Use Twitter/X as confirmation for existing candidates when cookies or bearer auth are configured
- Score freshness, quality, source diversity, and sentiment direction
- Send top candidates to LLM research
Trading (Market Hours Only)
- Check existing positions for stop-loss/take-profit
- Ask LLM to analyze each position (HOLD/SELL)
- Look for buy opportunities from researched, scored candidates
- Execute trades via PolicyBroker (PolicyEngine validation to Alpaca)
- Record buy, sell, skip, and blocked decisions for trade-review export
LLM Decision Making
Signal Research
For each trending stock, the LLM receives:
- Symbol and current price
- Sentiment score and volume
- Source breakdown, quality score, catalysts, and freshness
It returns:
{
"verdict": "BUY" | "SKIP" | "WAIT",
"confidence": 0.0-1.0,
"reasoning": "explanation",
"red_flags": ["concerns"],
"catalysts": ["positive factors"]
}
Position Analysis
For each held position, the LLM receives:
- Symbol, shares, P&L percentage
- Current sentiment (if still trending)
- Take profit/stop loss targets
It returns:
{
"action": "HOLD" | "SELL",
"confidence": 0.0-1.0,
"reasoning": "explanation"
}
Order Flow
The autonomous agent and external tools use different paths, but both pass through the same PolicyEngine validation.
Autonomous Agent (Harness)
The harness calls PolicyBroker directly, which wraps PolicyEngine.evaluate() and submits to Alpaca in a single step. The policy engine validates:
- Kill switch not active
- Not in cooldown period
- Within position limits
- Within daily loss limits
- Sufficient buying power
If validation passes, the order is executed immediately through Alpaca.
External Tools (MCP — Claude Desktop, etc.)
External integrations use the two-step orders-preview / orders-submit MCP flow. Preview returns an approval token (valid 5 minutes); submit executes the order through Alpaca using that token.
MCP Tools
The MCP server at /mcp exposes tools for external integrations (e.g., Claude Desktop). Key tools:
| Category | Tools |
|---|---|
| Account | accounts-get, portfolio-get |
| Positions | positions-list, positions-close |
| Orders | orders-preview, orders-submit, orders-list, orders-cancel |
| Market Data | market-clock, market-quote, market-movers |
| Technicals | technicals-get, signals-get |
| Risk | risk-status, killswitch-enable, killswitch-disable |
For daily operation, use Sentinel or the /agent/* HTTP endpoints instead (see Sentinel and Configuration).
Project Structure
MAHORAGA-Next/
├── wrangler.jsonc # Cloudflare config
├── .dev.vars # Local secrets (gitignored)
├── src/
│ ├── index.ts # Entry point & routing
│ ├── core/
│ │ ├── types.ts # Shared types (Signal, AgentState, etc.)
│ │ └── policy-broker.ts # PolicyEngine-wrapped broker
│ ├── durable-objects/
│ │ └── mahoraga-harness.ts # Core orchestrator (~1,400 lines)
│ ├── strategy/
│ │ ├── types.ts # Strategy interface contract
│ │ ├── index.ts # Active strategy selector
│ │ └── default/ # Default strategy
│ │ ├── gatherers/ # StockTwits, Reddit, SEC, GDELT, Alpha Vantage, crypto, Twitter/X
│ │ ├── prompts/ # LLM prompt templates
│ │ ├── rules/ # Entry/exit/staleness/options rules
│ │ └── helpers/ # Ticker extraction, sentiment
│ ├── mcp/ # MCP server (external tools)
│ ├── policy/ # Trade validation & risk engine
│ ├── providers/ # Alpaca, LLM providers
│ ├── storage/ # D1 and KV storage
│ └── schemas/ # Config schemas (Zod)
├── dashboard/ # React dashboard, Electron app, Capacitor Android shell
├── docs/ # Documentation
└── migrations/ # D1 database migrations