Files
alpaclaudia/docs/RUNBOOK.md
T
admin f2caca9175 docs: add ARCHITECTURE, RUNBOOK, CHANGELOG; reset .env.example to placeholders
ARCHITECTURE.md: system overview, data flow, SQLite schema, guard rails,
  risk gates, wheel flow, guide for adding new strategies.
RUNBOOK.md: day-to-day ops, config reference, troubleshooting, safe shutdown,
  upgrade procedure.
CHANGELOG.md: v0.1.0 + v0.1.1 (limit_price fix).
.env.example: credentials removed, URL /v2 suffix stripped.
2026-04-16 22:15:08 +02:00

140 lines
4.5 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.
# Runbook
## Day-to-day
### Check if the bot is alive
```bash
systemctl --user status alpaclaudia-loop.service
journalctl --user -u alpaclaudia-loop.service -n 30
```
### Manual tick (one-shot, uses current BOT_MODE)
```bash
cd ~/finhacks && bot/.venv/bin/python -m alpaclaudia tick
```
### Account + position snapshot (CLI)
```bash
cd ~/finhacks && bot/.venv/bin/python -m alpaclaudia status
```
### Post Discord report manually
```bash
cd ~/finhacks && bot/.venv/bin/python -m alpaclaudia report
```
### Dump SQLite state (JSON, last 50 ticks/intents)
```bash
cd ~/finhacks && bot/.venv/bin/python -m alpaclaudia dump-state
```
### Dashboard
```
http://192.168.0.93:3030/ (browser)
http://192.168.0.93:3030/api/refresh (raw JSON)
```
---
## Config changes (~/finhacks/.env)
| Change | Key | Action after |
|---|---|---|
| Add symbol to universe | `WHEEL_UNIVERSE` | Service auto-picks up on next tick (no restart needed — env file is reloaded each run) |
| Change DTE window | `WHEEL_PUT_DTE_MIN/MAX` | next tick |
| Change trail % | `TRAILING_STOP_PCT` | next tick |
| Disable trailing stops | `TRAILING_STOP_ENABLED=false` | next tick |
| Go live on paper | `BOT_MODE=live` | `systemctl --user restart alpaclaudia-loop` |
| Switch to real account | `ALPACA_ENV=live` + live key/secret | **Careful.** Restart service. |
Note: the bot reloads `.env` on every process start, but the systemd service runs as a single long-lived process. Config changes only apply after a restart unless the service is in loop mode and you run a manual tick with the new env.
To force an env reload: `systemctl --user restart alpaclaudia-loop.service`
---
## Troubleshooting
### "limit price must be limited to 2 decimal places"
Fixed in `executor.py`. Should not recur. If it does: check if a new order type path is missing `round(..., 2)`.
### "insufficient cash" block
The CSP collateral exceeds `cash equity * MIN_CASH_BUFFER_PCT`. Either:
- The underlying's spot moved up and the closest strike now requires more cash.
- Other positions consumed cash (assignments).
- Increase `MIN_CASH_BUFFER_PCT` or reduce `MAX_POSITION_PCT` or pick cheaper underlyings.
### "collateral exceeds per-symbol cap"
Strike * 100 > `equity * MAX_POSITION_PCT`. Default is 25%. TSLA at ~$370 = $37k collateral; needs `MAX_POSITION_PCT >= 0.37`.
### "no long stock to cover"
Phase 2 (covered call) triggered but position was closed / not assigned yet. Normal — next tick it resolves.
### Options chain returns empty
Alpaca may not have an active options chain for that symbol, or DTE window yields no contracts. Check:
```bash
cd ~/finhacks && bot/.venv/bin/python -c "
from alpaclaudia.config import load_config
from alpaclaudia.client import build_clients, list_option_contracts
cfg = load_config()
from alpaclaudia.client import Clients
import os; from dotenv import load_dotenv; load_dotenv()
from alpaca.trading.client import TradingClient
from alpaca.data.historical.stock import StockHistoricalDataClient
from alpaca.data.historical.option import OptionHistoricalDataClient
tc = TradingClient(cfg.alpaca.key, cfg.alpaca.secret, paper=True)
sd = StockHistoricalDataClient(cfg.alpaca.key, cfg.alpaca.secret)
od = OptionHistoricalDataClient(cfg.alpaca.key, cfg.alpaca.secret)
clients = Clients(trading=tc, stock_data=sd, option_data=od)
contracts = list_option_contracts(clients, 'SOFI', option_type='put', dte_min=7, dte_max=45)
print(len(contracts), 'contracts')
"
```
### Service fails to start
```bash
journalctl --user -u alpaclaudia-loop.service -n 50 --no-pager
```
Common cause: `.env` missing or Alpaca credentials empty.
---
## Stopping the loop safely
```bash
systemctl --user stop alpaclaudia-loop.service
```
Open orders in Alpaca are **not** cancelled — they remain until filled or expire (DAY orders expire at market close). To cancel all open orders manually:
```bash
cd ~/finhacks && bot/.venv/bin/python -c "
from alpaclaudia.config import load_config
from alpaclaudia.client import build_clients
cfg = load_config()
clients = build_clients(cfg.alpaca)
clients.trading.cancel_orders()
print('all open orders cancelled')
"
```
---
## Extending the universe
Edit `WHEEL_UNIVERSE` in `~/finhacks/.env`:
```
WHEEL_UNIVERSE=TSLA,SOFI,PLTR,NIO,BAC,F,HOOD,RIVN,LCID
```
Good candidates: liquid, optionable, strike < $50 to stay within $5k collateral per lot at the default 25% cap on a $100k account.
---
## Upgrading the bot
```bash
cd ~/finhacks
git pull
cd bot && .venv/bin/pip install -e ".[dev]"
systemctl --user restart alpaclaudia-loop.service
```