SILVER LYNX QUANT
team entry · Alpaca paper trading

Alpaca AI Trading Agents Hackathon · lablab.ai · competition entry

AI judgment, without AI-sized risk.

Silver Lynx is a live options-execution agent with a deliberately small AI action space: veto or resize an already-approved trade. It cannot invent a symbol, widen a gate, or chase the ask. Every intervention is journaled and replayable.

34,292
decisions journaled & queryable
~10
kill-switchable risk gates before the AI
[0, 2×]
hard clamp on every AI resize
143 / 143
tests passing (incl. the adversarial fill test)
Alpaca paper account · live 24/7 MCP client & server fails open 100% auditable agent closed alpha, open execution occ-symbol · npm + PyPI

Watch the demo

See it run — a builder's tour

A short walk-through of the bounded overlay, the decision journal, and the arrival-anchored fill engine — narrated by the person who built it. The site is the reference; this is the guided tour.

demo video — dropping in before the submission

The honest headline

How the AI's value is measured

Not a hand-wavy account race. Measured trade-by-trade, where the AI actually acts — at the decision.

Decision-journal audit

The three live cells differ in more than the AI — different holding-period windows, different leverage — so any raw account-vs-account P&L delta is confounded. Instead, the AI's contribution is measured where it happens: every candidate the agent evaluates appends one structured JSON line recording what the deterministic gate decided and, on the flagship, exactly how the AI modified it.

✕ The tempting-but-wrong claim

"Three identical cells; the account delta is the AI." — It isn't. The cells carry different DTE windows and leverage, so a P&L gap can't isolate the model's judgment.

✓ What we actually claim

A per-trade, replayable audit trail. Filter the journal to the flagship's AI interventions and read, one by one, every candidate it vetoed and every one it up- or down-sized — with the gate's original decision alongside.

THE AI'S ENTIRE ACTION SPACE — a size factor on an already-cleared candidate
0× — veto
1× — gate size
2× — max resize

The AI can only move a candidate inside this clamp. It can never widen a gate, invent a name, or add risk the deterministic layer didn't already clear — so its footprint is fully separable from the strategy's. The journal is live-queryable over a read-only MCP tool: a judge points their own LLM at the running system.

Why it stands out

Five things a judge can verify

Each is backed by captured evidence below — a log line, a test, a journal record.

1

The AI proves its worth line by line

Every candidate is journaled with what the deterministic gate decided and exactly how the AI moved it — veto to size 0, or resize within [0, 2×]. 34,292 decisions logged; every AI intervention auditable — not a fuzzy account race.

2

A rising ask cannot make us overpay

One absolute-dollar ceiling, anchored to the arrival quote, clamps every rung, walk step, spray shot and sweep. A test drives the ask up +50% mid-fill and asserts no recorded price ever crosses it.

3

A costly API bill → a two-tier token budget

One raw feed position is tens of thousands of tokens. Serialized whole, it burned real money against a hard prepaid cap. We project it to a few hundred curated scalars — roughly 30× cheaper per call, and the model sees more structured signal. Receipt: raw ~114k–255k chars → compacted ≤ ~3k chars (see evidence/token-budget.md).

4

Bounded by math, and it fails open

A forced tool-call lets the model only reject (size 0) or resize within [0, 2×]; leg prices are clamped to [0, 1] of the spread — a hard guarantee against the classic chase-the-ask failure. If the model errors, the proven strategy keeps trading.

5

An MCP client and a read-only MCP server

It places real orders through Alpaca's official MCP server, and exposes its own inspection server so a grader's LLM can reason over live account state — every decision returned as a queryable JSON line.

POCKET FLEX

occ-symbol — dual-published open-source plumbing

A zero-dependency OCC option-symbol parser on npm + PyPI. The Python port reimplements JavaScript's half-away-from-zero rounding (Python's round() uses banker's rounding) so the two stay byte-identical on exact half-thousandth strikes. Mis-parsed option tickers route orders to the wrong contract — this is the boring, money-saving plumbing done right.

The pipeline

Closed alpha in. Open, auditable execution out.

Signals cross a single thin, read-only, typed socket. Everything downstream is in the open repo.

Signal desk · closed
Proprietary Research Engine
private alpha — a black box
read-only
typed socket
gate
Risk Gauntlet
~10 kill-switchable gates; every skip journaled
survivors
only
overlay · bounded
AI Overlay
veto or resize [0, 2×] · fails open
clamped
fill plan
venue
MCP Execution
real orders via Alpaca's official MCP server
closed / proprietary (not judged) open, auditable agent (what you're judging) the bounded AI overlay

The quant-shop split. The trust boundary is one-directional and minimal: signals flow in as bounded scalars — conviction scores, a hold-tier, a market-regime context — with no shared code and no RPC into the engine's internals. There is no write-back path. The alpha proposes; the risk-aware AI agent disposes — and every knob in that disposal is in the open repo.

The portfolio, honestly described

Three live risk profiles. The flagship adds the AI.

Not a controlled experiment — a small fleet of distinct risk profiles, one of which layers the bounded AI overlay onto the same deterministic machinery.

Cell Risk profile Holding window Leverage AI overlay
Cash sleeve conservative 14–30 DTE (longer-dated) ~100% — off
Margin sleeve aggressive 2–7 DTE (short-dated) ~100% — off
Compete FLAGSHIP widest window, favors short 2–30 DTE (any, favors short) ~190% ● on · bounded overlay

Matched across all three (same deterministic machinery): the same conviction floor · the same per-name position cap · the same minimum hold-tier · the same pacing and entry filters. The flagship is where the AI overlay layers in — which is why the decision journal, not an account comparison, is the primary evidence of its value.

Captured, verifiable

Evidence

Verbatim from the live cells and the test suite. Proprietary score names genericized; account fields redacted.

The decision journal — the AI in action

data/decisions.jsonl · 34,292 records

A BUY record carries the AI's fingerprint: sizeFactor (the bounded resize) and a plain-English reason that cites the gate state. Below, the model overrides a conflicting bearish flag with disciplined, reduced sizing — exactly the judgment the overlay exists to add.

// genericized · one JSON line per candidate
{
  "ts": "2026-09-02T15:20:19.866Z", "action": "BUY", "executed": true,
  "reason": "gated+selected+sized · strong conviction with max-conviction regime
            flag set, conviction well above floor; 2 DTE warrants a
            sized-up entry inside the spread with a walk backstop.",
  "gatePct": 0.37, "governor": 1, "dte": 2, "qty": 91,
  "execMode": "between",
  "execPlan": [
    { "mode":"between", "qtyPct":0.7, "lowFrac":0.0, "highFrac":0.5 },
    { "mode":"walk",    "qtyPct":0.3, "lowFrac":0.5, "highFrac":1.0 }
  ],
  "sizeFactor": 1.8   // ← the AI's bounded resize, clamped to [0, 2×]
}

The funnel is the point: 16,725 SKIP · 13,221 CONSIDER · 4,221 HOLD · 86 BUY · 39 CLOSE. Tens of thousands of candidates, 86 buys — the agent's default answer is no.

Not just auditable — audited. One pass over the journal, across every sized entry: 18 upsized · 34 downsized · 34 held at gate size · median sizeFactor 1.0. ~60% of sized entries were actively re-sized by the AI — a bounded overlay that tunes, not one that takes over. (Vetoes size to zero and never reach the buy log — the caution shows up upstream as a skip. Counts only.)

Real orders via Alpaca's MCP

[mcp-venue]

Verbatim log. The price staircase on one contract is the multi-leg fill plan — resting inside the spread and walking the remainder, never one market order at the ask.

ok buy  5 <contract> @0.53 (281ms)
ok buy  5 <contract> @0.55  (95ms)
ok buy  5 <contract> @0.57  (90ms)
# climbs INSIDE the spread — bounded
# above by the arrival ceiling →

Sub-300ms round trips. Venue swaps to REST with a single env flag — production-grade rollback.

The ask can't be chased — proven

execution.test.ts

An adversarial test drives the ask +50% mid-fill and asserts no placed price ever crosses the arrival-anchored ceiling.

// arrival ask 0.60 → 10% ceiling = 0.66
// ask then RISES to 0.90 mid-execution
 between + sweep: no price exceeds 0.66
 walk: stays anchored to PLAN arrival
 dry-run reflects the ceiling identically

ℹ pass 143   ℹ fail 0

Overpaying is made unrepresentable, then pinned down by a test.

Captured, verifiable — cont.

Both sides of MCP work

The agent is an MCP client and a read-only MCP server — and the read-only surface is safe to hand a judge's LLM.

Client reads live state · server exposes only read tools

npm run mcp:smoke

Client side, live box: launches Alpaca's official server over stdio, enumerates tools, round-trips real reads.

🖥  Server: Alpaca MCP Server, 3.4.7
✓ MCP connected — 72 tools exposed

── get_clock
{"is_open":false,"next_open":"09:30-04:00"}
── get_account_info
{"status":"ACTIVE","options_trading_level":3}

Server side: the agent exposes its own read-only surface. Read tools are safe for a grader's LLM; mutating tools are never exposed.

slq_get_account     read   ✓ expose
slq_get_positions   read   ✓ expose
slq_get_decisions   read   ✓ expose  # the journal
slq_status          read   ✓ expose
slq_place_buy       mutate ✕ never
slq_close_position  mutate ✕ never

Open-source plumbing

occ-symbol — shipped, dual-published, byte-identical

SPY260825C00500000
UNDERLYINGSPY
EXPIRY2026-08-25
RIGHTCall
STRIKE$500.00

Correctness as first-class

A mis-parsed strike routes an order to the wrong contract — a notorious source of silent, money-losing bugs in options code.

The Python port reimplements JavaScript's half-away-from-zero rounding — because Python's built-in round() uses banker's rounding and would disagree on exact half-thousandth strikes. Test fixtures mirror 1:1 across both languages.

Shipping this as OSS signals a team that treats the closed alpha upstream to the same standard — we just don't give that part away.

The framing

The alpha proposes. The risk-aware AI agent disposes.

Silver Lynx is the execution-and-risk desk; our proprietary research engine is the signal desk — separated on purpose, exactly like a real quant shop. The engine stays a black box; the agent is 100% open and is what you're judging. They touch through a single typed, read-only socket that returns bounded scalars — conviction scores, hold tiers, a market-regime context — with no shared code and no RPC into the engine's internals. The agent doesn't obey the signal; it re-derives its own gates, its own sizing, its own execution policy, and an LLM overlay that can veto or resize. Every knob in that disposal is in the open repo.

Signal desk

Proprietary research engine. Produces bounded scalars only — never code, never RPC.

🔒 closed · not judged
one typed read-only socket · signals in, no write-back

Execution & risk desk

Gates, sizing, MCP execution, and the bounded AI overlay. The agent physically cannot leak the edge — it never has it.

🔓 100% open · judged

The takeaway

The alpha stays a black box. The agent is 100% auditable — and the AI's contribution is provable trade-by-trade.

A fully-transparent, LLM-in-the-loop options-execution agent: bounded by math, failing open toward a proven strategy, executing MCP-native both ways, with every decision a queryable JSON line.

34,292 decisions journaled AI clamped to [0, 2×] MCP client + read-only server 143/143 tests green occ-symbol · npm + PyPI