Files
alpaclaudia/README.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

98 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# alpaclaudia
Automated **Alpaca paper-trading bot** with a **Next.js dashboard**.
Strategy coverage today:
- **Wheel** — sells cash-secured puts on a configurable universe, rolls into covered calls after assignment.
- **Trailing stops** — on every long equity position (opt-in).
Safety first: by default `BOT_MODE=dry` — the bot plans and logs intents but **submits nothing** to Alpaca. Flip to `live` only after you've reviewed the intent log.
```
finhacks/
├── bot/ # Python 3.11+ trading bot (alpaca-py, SQLite state)
├── dashboard/ # Next.js 14 dashboard (read-only view of bot + Alpaca)
├── systemd/ # user-unit templates for loop + daily report
├── data/ # SQLite DB lives here (gitignored)
├── logs/ # bot logs (gitignored)
└── docs/ # extra docs
```
## Quick start (paper)
```bash
# 0. prerequisites: Python 3.11+, Node 20+, a paper Alpaca account
# 1. credentials
cp .env.example .env
# edit .env and set ALPACA_API_KEY, ALPACA_API_SECRET
# leave BOT_MODE=dry for the first few runs
# 2. bot
cd bot
python -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/python -m alpaclaudia status # smoke test
.venv/bin/python -m alpaclaudia tick # one dry iteration
# 3. dashboard
cd ../dashboard
cp .env.example .env.local
# set ALPACA_API_KEY + ALPACA_API_SECRET (same paper creds)
npm install
npm run dev # http://localhost:3030
# 4. schedule (optional, systemd user units)
# see systemd/README.md
```
## How a tick runs
```
scheduler.tick()
├─ snapshot account / positions / orders (Alpaca)
├─ record_tick() → SQLite
├─ plan_wheel() ── produces OrderIntent[]
├─ plan_trailing_stops() ── produces OrderIntent[]
├─ risk.check_*() ── per intent; blocked → logged, never submitted
└─ executor.submit_intent() ── no-op in dry-run; else Alpaca REST
```
Everything the bot considers ends up in `data/alpaclaudia.db::order_intents`, whether submitted, blocked, or dry-run. The dashboard reads this table verbatim, so you can audit the bot's reasoning independently of Alpaca.
## Going live (on paper — still "paper" at Alpaca)
After reviewing a couple of dry runs:
```bash
# in .env
BOT_MODE=live
ALPACA_ENV=paper # still paper account — don't touch this unless you mean it
```
`ALPACA_ENV=live` is a separate, explicit guard that flips the SDK to the production endpoint. Don't set it unless you really want real money at stake.
## Daily Discord report
Set `DISCORD_WEBHOOK_URL` in `.env` and enable the timer:
```bash
systemctl --user enable --now alpaclaudia-report.timer
```
It fires MonFri at 22:30 local time (≈30 min after NYSE close if you're in Europe).
## Risk invariants (code in `bot/alpaclaudia/risk.py`)
- CSPs require `strike * 100 * qty ≤ cash equity * MIN_CASH_BUFFER_PCT`.
- CSP collateral per symbol capped at `MAX_POSITION_PCT` of equity.
- Covered calls only sell above cost basis — never locking in a loss.
- Covered calls require ≥ `qty*100` underlying shares already held.
- Trailing stops only on long equity positions we own.
Tests: `cd bot && .venv/bin/pytest`.
## Repo
- Mirror: https://git.zeitanker.digital/admin/alpaclaudia