CoolFace
Apppublic

HARSHARAVURI/stoker-mft

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
App README

Stoker MFT — Multi-Agent Medium-Frequency Trading Simulation

A paper-trading simulation environment powered by a LangGraph-orchestrated committee of 6 specialized AI agents. Scans markets 24/7 — executing live during market hours and queuing proposals off-hours for execution at open.

No real orders are executed by default. This is a research and simulation tool only.

Live: huggingface.co/spaces/HARSHARAVURI/stoker-mft


Agent Pipeline

──────────────── Market Hours ────────────────────────────────
[Auto-scanner: every 15 min during NSE / NYSE hours]
        │
        ▼
Fundamental → Screener → Quant → Risk ──APPROVED──► Execution (Meta)
                                    └──REJECTED──► END

──────────────── Off-Hours / Holidays ────────────────────────
[Hourly pre-market scan]
        │
        ▼
Fundamental → Screener → Quant → Risk ──APPROVED──► Queue Node → trade_queue DB
                                    └──REJECTED──► END

[On market open (non-holiday)] → drain trade_queue → Execution (Meta)
AgentRole
FundamentalScrapes news/macro data via DuckDuckGo + Finnhub, synthesizes market theme and sector bias
ScreenerScans universe for RVOL ≥ 1.2 and avg volume ≥ 2M, LLM narrows to 3–5 in-play tickers aligned with theme
QuantRuns RSI, MACD, Bollinger Bands, VWAP, EMA 9/21 crossover on 15-min candles, proposes one trade with confidence score
RiskDeterministic veto: ATR stop-loss, 1% sizing rule, max 5 positions, duplicate check — all rejections logged with reason
QueueOff-hours only — saves approved proposals to trade_queue table instead of executing
Execution (Meta)Applies entry slippage, generates final LLM rationale, writes to ledger, updates portfolio cash, routes to broker

LLM Stack

PriorityProviderModelNotes
PrimaryGoogle AI Studiogemma-3-27b-itFree tier
FallbackOpenAIgpt-5-nanoReleased August 2025

Market Coverage

MarketSession (local)Session (IST)Universe
NSE India09:15–15:30 IST Mon–Fri—34 Nifty 50 stocks
NYSE US09:30–16:00 ET Mon–Fri19:00–01:30 IST30 S&P 500 stocks

Scheduling Logic

ConditionBehaviour
Market open, non-holidayLive scan every SCAN_INTERVAL_MINUTES (default 15 min), execute immediately
Market closedOff-hours scan every OFFHOURS_SCAN_INTERVAL_MINUTES (default 60 min), proposals queued
Market holidayTime window ignored — treated as off-hours all day, queue drain blocked
Market just opened (non-holiday)Queue drain fires once, all PENDING proposals executed via Meta agent
Queue entry > 20 hours oldAuto-expired before drain (missed the trading session)
Every SundayHoliday calendar refreshed via Tavily / DuckDuckGo for the coming week

Risk Rules (Deterministic — Not LLM-Overridable)

RuleValue
Max risk per trade1% of portfolio equity
Stop-loss1.5 × ATR from entry
Take-profit3.0 × ATR from entry (2:1 R:R minimum)
Max open positions5 concurrent
Min confidence0.45
Session kill switchHalts all new trades if session loss > 5% of equity

Observability — What Gets Logged

Structured logs (Logs tab — JSON-lines, IST timestamps)

EventWhenKey Fields
trade_proposedQuant proposesAsset, direction, entry, confidence, rationale, RSI, EMA cross, MACD, Bollinger %B, VWAP, signal bias
trade_rejectedRisk or Quant rejectsAsset, stage, reason, confidence, proposed entry
trade_openedApproved and loggedTrade ID, asset, direction, entry, SL, TP, size
trade_closedTP/SL/timeout hitTrade ID, close price, realized P&L
cycle_startEach scan beginsMarket (IN/US)
errorAny unhandled exceptionContext, error message

learnings.md (project root — auto-appended on every trade close)

Each entry contains: entry rationale, market theme, planned R:R, confidence, close price, actual P&L, and a templated lesson per outcome type (WIN / LOSS / TIME). Accumulates over time as institutional memory for the system.


UI Tabs

TabContents
Live ConsoleAuto-scanner status (market state, holiday indicator, upcoming holidays), manual scan button, streaming pipeline output
Trade LedgerAll trades table + Trade Intelligence panel (click any row to expand full entry/exit breakdown, agent decision chain, R:R metrics) + Pre-Market Queue table (PENDING / EXECUTED / EXPIRED proposals)
PerformanceWin rate, R-multiple, avg win/loss, total P&L, Plotly cumulative equity curve
Calibration & Live GateConfidence ECE score, per-bucket predicted vs actual win rate, live trading gate criteria checklist
LogsFilterable execution log (ALL / ERROR / WARNING / INFO) — proposals with full indicator snapshot, rejections with reason

Trade Intelligence Panel

Clicking any row in the Trade Ledger expands a full breakdown:

  • —Why we entered — market theme (Fundamental agent), Portfolio Manager's LLM rationale, confidence gauge
  • —Position metrics — entry / TP / SL with % distances, notional value, max reward, max risk, R:R ratio
  • —Why we exited — contextual explanation per status:
  • —OPEN — conditions that will trigger a close, time in trade so far
  • —CLOSED_TP — "Take Profit hit" with close price vs plan
  • —CLOSED_SL — "Stop Loss triggered" with loss vs max risk
  • —CLOSED_TIME — actual price move over hold period, neither target reached
  • —Agent decision chain — table showing each agent's specific decision for this trade

Local Setup

bash
pip install -r requirements.txt
cp .env.example .env    # add GOOGLE_API_KEY at minimum (free at aistudio.google.com)
python app.py           # Gradio UI → http://localhost:7860
python run_cycle.py                       # single IN market cycle (CLI)
python run_cycle.py --market US           # single US market cycle (CLI)
python feedback_loop.py --days 7 --save  # weekly review + save suggestions

Environment Variables

Required (at least one LLM key)

VariablePurpose
GOOGLE_API_KEYPrimary LLM — Gemma 3 27B via Google AI Studio (free)
OPENAI_API_KEYFallback LLM — gpt-5-nano

Optional

VariableDefaultPurpose
FINNHUB_API_KEY—Enhanced company news via Finnhub
TAVILY_API_KEY—Holiday calendar fetching (falls back to DuckDuckGo if unset)
DATABASE_URLSQLitePostgreSQL connection string — recommended for HF Spaces (Neon / Supabase)
ADMIN_USER / ADMIN_PASS—Gradio basic auth
TELEGRAM_BOT_TOKEN / TELEGRAM_CHAT_ID—Trade alerts via Telegram
ALERT_EMAIL_FROM / ALERT_EMAIL_TO / ALERT_EMAIL_PASSWORD—Trade alerts via email
AUTO_SCAN_ENABLEDtrueSet false for manual-only mode
SCAN_INTERVAL_MINUTES15Live scan frequency (market hours)
OFFHOURS_SCAN_INTERVAL_MINUTES60Off-hours / holiday scan frequency
TRACKER_INTERVAL300Mark-to-market check interval (seconds)
MAX_HOLD_HOURS48Auto-close positions older than N hours
MIN_CYCLE_MINUTES10Minimum gap between pipeline runs (rate limit)
MAX_SESSION_DRAWDOWN_PCT0.05Kill switch threshold (5% session loss)

Live Trading (only when gate is passed)

VariablePurpose
LIVE_TRADINGSet true to enable real order routing
BROKERalpaca (US) or zerodha (India)
ALPACA_API_KEY / ALPACA_SECRET_KEYAlpaca Markets credentials
ALPACA_PAPERtrue = Alpaca paper account
ZERODHA_API_KEY / ZERODHA_ACCESS_TOKENZerodha Kite Connect credentials
Without DATABASE_URL, SQLite is used — trade data and the queue reset on every HF Space restart. Set a Neon or Supabase DATABASE_URL for persistence.

Live Trading Gate

Blocked until all four criteria are met (checked programmatically before every live order):

CriterionThreshold
Closed trades≥ 100
Win rate≥ 52%
R-Multiple≥ 1.0
Sharpe ratio≥ 1.0

Project Structure

stoker_mft/
├── app.py                    Gradio UI (5 tabs)
├── run_cycle.py              CLI test runner
├── feedback_loop.py          Weekly performance review
├── learnings.md              Auto-generated trade learnings log (appended on every close)
├── holidays.json             Cached market holiday calendar (refreshed every Sunday)
├── requirements.txt
├── Dockerfile / run.sh       HF Docker Space
│
├── graph/
│   ├── state.py              TradingDeskState TypedDict (includes queue_mode flag)
│   ├── graph.py              LangGraph wiring (Execution + Queue nodes)
│   └── nodes/
│       ├── fundamental.py    News → market theme + bias
│       ├── opportunity.py    RVOL scanner → watchlist
│       ├── quant.py          Indicators → trade proposal (logs indicator snapshot)
│       ├── risk.py           Deterministic veto (logs every rejection with reason)
│       ├── meta.py           Slippage + ledger + broker (market-hours execution)
│       └── queue_node.py     Off-hours — saves approved proposal to trade_queue table
│
├── tools/
│   ├── llm_factory.py        Gemma 3 27B → gpt-5-nano fallback chain
│   ├── market_data.py        yfinance wrappers + ticker validation
│   ├── indicators.py         RSI, MACD, Bollinger, VWAP, EMA 9/21, ATR
│   ├── news_scraper.py       DuckDuckGo + Finnhub news
│   ├── holiday_calendar.py   Tavily/DDGS holiday fetch, is_holiday(), weekly Sunday refresh
│   ├── slippage.py           Entry/exit slippage simulation + commission
│   ├── broker.py             Zerodha + Alpaca order routing
│   ├── live_gate.py          Live trading validation gate
│   ├── kill_switch.py        5% session drawdown halt
│   ├── alerts.py             Telegram + email notifications
│   ├── logger.py             IST-aware JSON-lines structured logging
│   └── scheduler.py          24/7 scanner — live, off-hours, holiday, queue drain, Sunday fetch
│
├── database/
│   ├── schema.sql            trades, agent_runs, portfolio, trade_queue tables
│   ├── ledger.py             SQLite/PostgreSQL CRUD + Postgres compatibility layer
│   ├── tracker.py            Mark-to-market background loop (TP/SL/time exits)
│   ├── queue.py              Trade queue CRUD (enqueue, drain, expire)
│   └── learnings.py          Auto-appends to learnings.md on every trade close
│
└── logs/                     Daily JSON-lines logs (IST timestamps, auto-created)