◆ INTEGRATIONS

Broker setup

Connecting a broker is optional — the free tier works fine on public Yahoo Finance data. Adding E*Trade unlocks live positions. Adding Tradier gives you better market data + Greeks. Both tokens live in your local .env file; they never reach our servers.

E*Trade

E*Trade uses OAuth 1.0a with two modes: sandbox (fake data, safe to experiment) and production (your real account). Always start in sandbox.

Step 1 — get your consumer key/secret

  1. Log into E*Trade.
  2. Go to Customer Service → Technical Support → Developer Platform.
  3. Apply for API access. Approval is typically 1-2 business days.
  4. Once approved you'll receive a Consumer Key and Consumer Secret for both sandbox and production.

Step 2 — add them to .env

# E*Trade API (Phase 1 — read-only by default)
ETRADE_CONSUMER_KEY=your_consumer_key_here
ETRADE_CONSUMER_SECRET=your_consumer_secret_here
ETRADE_MODE=sandbox           # or "production"
ETRADE_ACCOUNT_ID=your_account_id  # find in E*Trade portfolio URL

Step 3 — first authorization flow

Restart control_server.py. The first time you make an E*Trade call the dashboard opens a browser window asking you to approve access. After approval, tokens are cached in etrade_tokens.json (gitignored). The access token lasts until midnight ET; Swing Deck auto-refreshes.

⚠ TWO-ACCOUNT SETUP If you have multiple brokerage accounts under one E*Trade login, set ETRADE_ACCOUNT_ID to the specific account you want Swing Deck to read. Mismatched account ID is the #1 cause of "positions missing from dashboard".

Tradier

Tradier gives you better quote latency and full options chains (including Greeks). You don't need a Tradier brokerage account — a free developer account works fine.

  1. Sign up at tradier.com.
  2. Go to dash.tradier.com/settings/api and generate an access token.
  3. Add to .env:
# Tradier — market data + Greeks (free tier works)
TRADIER_MODE=sandbox               # or "prod"
TRADIER_ACCESS_TOKEN=your_bearer_token

Tradier is used for the options barbell scanner (CSP, covered call) and to upgrade quote cadence from 60s to 10s.

Data providers

The audit engine has a tiered data cascade:

TierProvidersWhen used
1 (primary) Finnhub, MarketAux, News API Price + news + sentiment. Keys are free-tier (60-250 req/day each).
2 (secondary) Alpha Vantage, Google RSS, Stooq Falls through when Tier 1 quota exhausted.
3 (fallback) yfinance No key required. Always available. Rate-limited by Yahoo.
# Data provider keys (all optional — Tier 3 works without)
FINNHUB_API_KEY=your_key_here
MARKETAUX_API_KEY=your_key_here
NEWS_API_KEY=your_key_here
ALPHA_VANTAGE_API_KEY=your_key_here
⬡ PRO TIER UPGRADE Pro and Premium subscribers get access to a managed Polygon.io feed (real-time NBBO, 20-year historical, full options chain). Polygon is significantly faster than the public cascade — worth it if you're running intraday decisions.

Raise-Stop automation

The headline feature. Swing Deck can move your stop-loss orders up on E*Trade when a position hits a higher ATR-based trailing level. It never moves stops down. Ever.

Safety model — 4 guards

  1. Preview-confirm — every order goes through E*Trade's preview endpoint first. We compare the preview's computed stop against our logged stop. If they mismatch by more than $0.02, the place call is refused.
  2. Rate limiter — max 5 order modifications per minute per account. Prevents runaway loops.
  3. Staleness check — if the broker's view of the position is >300 seconds old, don't place. Better to miss a stop raise than act on stale data.
  4. Circuit breaker — 3 consecutive API failures → broker-writes auto-disabled for 30 minutes. Requires manual reset via POST /broker/circuit/reset.

Enablement checklist

⚠ READ BEFORE ENABLING LIVE MODE Broker writes start in dryrun mode (preview only, no order placed). Do not flip to live until you've run 1 full week in dryrun with clean audit logs.

In .env:

# ── Broker writes (Raise-Stop automation) ─────

# Master kill switch — leave false until you are 100% ready
BROKER_WRITES_ENABLED=false

# dryrun = preview only (safe, no orders placed)
# live   = preview + place (real order modifications)
BROKER_MODE=dryrun

# Safety throttles — don't change unless you know why
BROKER_MAX_ORDERS_PER_MIN=5
BROKER_STALE_MAX_SECONDS=300
BROKER_PARITY_TOLERANCE=0.02
BROKER_CIRCUIT_TRIP_COUNT=3
BROKER_CIRCUIT_COOLDOWN=1800

Verifying dryrun logs

Open broker_orders.log (created after the first run). Each line records one of:

Look for 1 week of clean preview_oks before flipping to live. Rate-limiter trips or parity mismatches → pause and investigate.