Alpaca paper-trading stack — read-only layer (stood up 2026-05-13)
What's installed
| Component | Path | Purpose |
|---|---|---|
| 1Password wrapper | ~/.claude/scripts/alpaca-env-paper.sh |
Pulls APCA_API_KEY_ID, APCA_API_SECRET_KEY, APCA_API_BASE_URL from 1Password "Ray Agent" vault, item "Alpaca Paper API Keys". Refuses to export non-paper URLs (safety guard). |
| Python venv | ~/.claude/scripts/alpaca-venv/ |
UV-managed Python 3.12 venv with alpaca-py SDK installed. First UV-managed venv in the script collection (existing venvs use plain python3 -m venv). |
| Smoke test | ~/.claude/scripts/alpaca-paper-smoke-test.py |
Read-only wiring check — pulls account, positions, orders, clock, AAPL quote. No writes. Refuses to run if base URL is not paper. |
Run the smoke test
bash -c 'source ~/.claude/scripts/alpaca-env-paper.sh && \
~/.claude/scripts/alpaca-venv/bin/python ~/.claude/scripts/alpaca-paper-smoke-test.py'
Expected first-run output (matches 2026-05-13 21:02 ET fire):
- Account status
ACTIVE, buying power $200,000, cash $100,000 (Alpaca paper default) - 0 positions, 0 orders
- Market clock reflecting current state
- AAPL quote (free-tier IEX-only data — see Caveats below)
Why these choices
- UV instead of plain venv for new Python work —
uv venvis dramatically faster thanpython3 -m venv, has a single-binary install, and gives us a real lockfile if we choose to useuv lock. Existing scripts (asc-api-venv, finance-venv, graph-db-venv) stay on plain venv until next-touch. - 1Password wrapper, not .env file — per [[~/.claude/projects/-Users-ray/memory/feedback_no_secrets_on_disk]]. Same pattern as
asc-api.sh,cloudflare-api.sh,commoncog-fetch-pw.py. - Paper-URL safety guard in the wrapper — if the 1Password URL field ever gets crossed with a live URL, the wrapper hard-refuses and exits. The live wrapper (when it exists) will be a separate file
alpaca-env-live.shthat hard-refuses non-live URLs in the opposite direction. Two scripts, two purposes, no chance of accidentally pointing the paper wrapper at live keys. paper=Trueflag on TradingClient explicitly set in the smoke test — the SDK infers paper-vs-live from this flag, not from base URL alone. Belt and suspenders.
What's NOT installed (deliberately)
- Order-wrapper / trade execution. Per the investing strategy-vs-execution boundary in [[01-projects/investing/README]]: founder authorizes via /decisions/, Ray executes against locked parameters. No write path exists yet. First trade execution will require:
- A wrapper function
place_order(side, symbol, qty, type, limit_price=None)with allowlist (initial: SPY, QQQ, AAPL) and per-trade size cap - JSONL audit log at
~/rdco-vault/01-projects/investing/_audit/orders-paper.jsonl - An open /decisions page naming the specific trade
- Founder explicit green-light in chat for the first execution
- A wrapper function
- Live trading wrapper. Live API key not yet created or funded per founder, 2026-05-13 evening. When that's enabled, the live wrapper will be a separate file with reciprocal safety guards.
- Alpaca MCP server. An unofficial one exists. Per [[~/.claude/projects/-Users-ray/memory/feedback_mcp_install_security_review_default]] would require security review before installing. Wrapper-script + Python is enough for now without the MCP overhead.
- WebSocket streaming. Only needed if we build a strategy that depends on intraday signals. Skip until needed.
Caveats observed in first smoke-test run
- AAPL quote at 21:02 ET showed $284.85 bid / $314.44 ask, $29.59 spread. Market closed (after-hours), free-tier data is IEX-only — those are stale/wide quotes from outside the regular session. Not a bug, just the limitation of the free data plan. If we need tight intraday quotes for execution decisions, upgrade to Alpaca's market-data subscription (~$9-99/mo depending on tier) or pull from a different vendor.
- Buying power = 2x cash because Alpaca paper accounts default to margin-enabled. For paper testing this is fine; if we want to mirror a strict cash-only discipline, we can either configure the paper account or just enforce in our own order-wrapper.
Cross-references
- [[01-projects/investing/README]] — investing project, strategy-vs-execution boundary
- [[01-projects/investing/decisions/2026-05-12-alpaca-account-status]] — parent decision page
- [[01-projects/investing/decisions/2026-05-13-alpaca-fpsl-enrollment-skip]] — related FPSL skip decision filed earlier today
- [[~/.claude/projects/-Users-ray/memory/feedback_no_secrets_on_disk]] — 1Password wrapper pattern
- [[~/.claude/projects/-Users-ray/memory/feedback_mcp_install_security_review_default]] — why we didn't auto-install the Alpaca MCP
Next steps (queued, not started)
- Order wrapper + audit log + first-trade decision page — separate session, founder green-light required.
- Strategy spec — first paper-trading thesis to test. Likely a simple buy-and-hold benchmark vs a small mechanical rule, just to exercise the order pathway end-to-end.
- Lockfile for the alpaca-venv — once we know which dependencies stick, run
uv pip freeze > requirements.txt(or migrate touv lockstyle) so the env is reproducible. - Migrate other venvs to UV — when we next touch asc-api-venv, finance-venv, graph-db-venv, switch them to UV. Not blocking; do at next-touch.