Files
alpaclaudia/docs/STRATEGY.md
T
admin 39875112a0 initial: alpaclaudia paper-trading bot + dashboard
Python bot (bot/alpaclaudia): alpaca-py client, wheel strategy (CSP + covered
calls) plus equity trailing stops, risk gates (cash buffer, cost-basis guard,
per-symbol concentration cap), SQLite state log, Typer CLI (tick/loop/status/
report/dump-state), Discord daily report, pytest suite.

Next.js 14 dashboard (dashboard/): read-only — reads the bot's SQLite directly
and pulls live account/positions/orders from Alpaca. KPIs, equity chart,
positions, bot-intents audit table, and orders table. Dark UI with Tailwind.

systemd/: user-unit templates for the polling loop and the post-close report
timer.

docs/STRATEGY.md: wheel mechanics, risk invariants, later candidates.

Defaults to BOT_MODE=dry — nothing is submitted to Alpaca until explicitly
enabled in .env. ALPACA_ENV=paper by default; flipping to live requires an
explicit second guard.
2026-04-16 21:38:25 +02:00

2.1 KiB

Strategy notes

The Wheel

A short-volatility, cash-secured income strategy. Two phases per underlying:

Phase 1 — no shares held: sell a cash-secured put (CSP). The bot picks a contract 14-28 DTE (WHEEL_PUT_DTE_MIN/MAX) with absolute delta closest to WHEEL_PUT_TARGET_DELTA (default 0.30). If the trade's annualised yield falls below WHEEL_MIN_ANNUAL_YIELD, it's skipped. If delta data is missing (Alpaca snapshot), it falls back to "closest to WHEEL_PUT_OTM_PCT below spot".

Two outcomes at expiry:

  • Put expires worthless → keep premium, repeat Phase 1.
  • Put is assigned → own 100 shares per contract at strike, go to Phase 2.

Phase 2 — shares held: for each uncovered 100-share lot, sell a covered call ~same DTE, same target delta, at or above cost basis (hard floor in risk.check_covered_call). Two outcomes at expiry:

  • Call expires worthless → keep premium, keep shares, sell another call.
  • Call is assigned → 100 shares called away at strike (a locked-in gain, because strike ≥ cost basis), back to Phase 1.

Assumption: the underlying is one we'd be happy to own. That's why WHEEL_UNIVERSE should be small and considered.

Trailing stops

Separate from the wheel — applies to any long equity position. On each tick, for every long stock position without an existing open trailing-stop order, the bot submits a trailing_stop sell at TRAILING_STOP_PCT trail.

In practice this is idempotent: duplicates are avoided by the open-order check.

Why not long calls / verticals?

Deliberately kept out of v0. They require managing more Greeks than the wheel and increase the surface area of risk mistakes. Easy to add under strategies/ once the wheel is stable on paper for weeks.

Candidates to consider later

  • Trailing-stop on short puts once they're deep ITM vs. the underlying's drift — close early and re-roll.
  • Cash-sweep into BIL/SGOV for idle cash while waiting for assignments.
  • Volatility filter — skip CSPs when IV rank is below a threshold (low premium).
  • Earnings blackout — skip CSP entries within N days of earnings.