Files
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

4.5 KiB
Raw Permalink Blame History

Runbook

Day-to-day

Check if the bot is alive

systemctl --user status alpaclaudia-loop.service
journalctl --user -u alpaclaudia-loop.service -n 30

Manual tick (one-shot, uses current BOT_MODE)

cd ~/finhacks && bot/.venv/bin/python -m alpaclaudia tick

Account + position snapshot (CLI)

cd ~/finhacks && bot/.venv/bin/python -m alpaclaudia status

Post Discord report manually

cd ~/finhacks && bot/.venv/bin/python -m alpaclaudia report

Dump SQLite state (JSON, last 50 ticks/intents)

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:

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

journalctl --user -u alpaclaudia-loop.service -n 50 --no-pager

Common cause: .env missing or Alpaca credentials empty.


Stopping the loop safely

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:

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

cd ~/finhacks
git pull
cd bot && .venv/bin/pip install -e ".[dev]"
systemctl --user restart alpaclaudia-loop.service