Fortress Script Reference
Usage guide for all 12 Python tools. Each section shows common command patterns, key flags, and a live preview of real output. All scripts run from ~/fortress/scripts/ using python3.
Flags auto-updated weekly — last refresh: 10 May 2026
Fortress Optimizer
fortress_v26.py
LEAPS Builder
leap_builder.py
CC Scanner
cc_scanner.py
Roll Calls
roll_calls.py
Fortress Rebuild
fortress_rebuild.py
FIGHT Recovery
fortress_fight.py
Fortress Repair
fortress_repair.py
Repair Trades
repair_trades.py
Stock Researcher
stock_researcher.py
Portfolio Dashboard
fortress_portfolio.py
Chain Exporter
fortress_export.py
GS Put Seller
gs_put_seller.py
Fortress Optimizer
fortress_v26.py β ~5100 lines
Three-archetype optimizer (PIONEER / DIAMOND / VAULT). Selects LC+SP+HP+SC strikes for minimum capital, max leverage.
Common Usage
Live IBKR β single ticker
python3 fortress_v26.py --live --tickers NVDA --contracts 10
Live β multiple tickers
python3 fortress_v26.py --live --tickers MSTR COIN BMNR --contracts MSTR:5 COIN:10 BMNR:20
From CSV (no IBKR needed)
python3 fortress_v26.py ~/fortress/runs/CSVs/NVDA_20260401.csv --contracts 10
Short-term mode + risk cap
python3 fortress_v26.py --live --tickers XLE --short-term --risk XLE:50k
Sigma analysis + parallel
python3 fortress_v26.py --live --tickers QQQ SPY --sigma --parallel 4
Key Flags
| Flag | Description | Default |
|---|---|---|
| csv_files | One or more fortress export CSVs. Required unless --live is used. | |
| --contracts | Contracts per ticker. Single number (e.g. --contracts 5) or | |
| --risk | Max loss budget per ticker in dollars. | |
| --fight-otm | FIGHT mode CC OTM%%%% from stressed stock (default: 0.01 = 1%%%%). | |
| --run-label | Custom label for output folder. Routes outputs to runs/{label}/ | |
| --dd-level | Max drawdown level for survival curve (default: 40, max: 90). | 40 |
| --drawdown-pct | Drawdown %% for stress testing (default: IV-scaled) | |
| --min-income-dte | Minimum DTE for income calls (default: 7) | 7 |
| --delta | SC delta cap for income calls (e.g. --delta 0.20). | |
| --sigma | Show CC sigma analysis in dashboard (e.g. --sigma 1.0). | |
| --tickers | Filter to specific tickers (e.g. --tickers TSLA NVDA) | |
| --no-dashboard | Skip HTML dashboard generation | |
| --no-json | Skip JSON results file | |
| --all | When --contracts has per-ticker overrides, include ALL tickers | |
| --landscape | Run landscape correlation analysis per ticker (verifies | |
| --short-term | Short-term income mode: uses all LEAPS chains (not just far), | |
| --live | Live mode: connect to IBKR TWS, fetch chains in real-time, | |
| --host | IBKR TWS host (default: {LIVE_HOST}) | LIVE_HOST |
| --port | IBKR port (default: auto-detect. Tries 4001 Gateway Live, | LIVE_PORT |
| --client-id | IBKR client ID (default: {LIVE_CLIENT_ID}) | LIVE_CLIENT_ID |
| --parallel | Number of parallel IBKR connections for live mode | 4 |
| --income-dte | DTE range for income calls in live mode (default: 5 46). | |
| --leaps-dte | DTE range for LEAPS in live mode (default: 180 9999, | |
| --publish | Publish dashboard to Cloudflare Pages via wrangler. | |
| --notify | Send push notification via ntfy.sh when dashboard is ready. | |
| --telemetry | v20.10: Always on (kept for backward compat). | True |
| --no-audit | Skip auto-generating audit HTML after scan. | False |
Output Location
runs/fortress/{TICKER}/latest.html
runs/fortress/{TICKER}/{TIMESTAMP}.html
runs/fortress/{TICKER}/audit_{TIMESTAMP}.html
runs/CSVs/{TICKER}_{TIMESTAMP}.csv β live mode only
LEAPS Builder
leap_builder.py β ~2120 lines
Builds optimal LC+SP+HP fortress structures for new tickers. Bucket A (deep ITM) vs Bucket B (OTM leverage), configurable split.
Common Usage
Single ticker, default split (50/50 ITM/OTM)
python3 leap_builder.py --tickers NVDA:250k
Multiple tickers, explicit mode
python3 leap_builder.py --tickers MSTR:100k:itm COIN:80k:otm
Custom budget split (70% ITM, 30% OTM)
python3 leap_builder.py --tickers GOOG:200k:both --budget-split 70/30
From CSV (skip IBKR)
python3 leap_builder.py --tickers XLE:150k --csv ~/fortress/runs/CSVs/XLE_chain.csv
Ticker Format
--tickers TICKER:BUDGET[:MODE]
MODE options:
itm β Bucket A only (deep ITM, income-focused)
otm β Bucket B only (OTM leverage play)
both β Split between A and B (default)
Key Flags
| Flag | Description | Default |
|---|---|---|
| --tickers | One or more positions. SIZE = 30k/100k/1m (budget) or 20c (contracts). | |
| --csv | Use a saved chain CSV (offline mode, skip IBKR). | |
| --cc-overlay | Scan CC overlay (short-dated calls above safe strike) | |
| --parallel | Parallel workers (live mode only, hard cap {PARALLEL_MAX_WORKERS}; | PARALLEL_MAX_WORKERS |
| --min-dte | Minimum DTE for LEAPS chain discovery (default: {MIN_DTE_DEFAULT}) | MIN_DTE_DEFAULT |
| --max-chains | Number of furthest-out chains to scan (default: {MAX_CHAINS}) | MAX_CHAINS |
| --html | Override HTML output path (default: routed via OutputManager) | |
| --audit | Override audit JSON output path (default: routed via OutputManager) | |
| --host | IBKR host (default: {DEFAULT_HOST}) | DEFAULT_HOST |
| --port | IBKR port (default: 0 = auto-detect | DEFAULT_PORT |
| --client-id | IBKR client ID (default: {DEFAULT_CLIENT_ID}) | DEFAULT_CLIENT_ID |
| --breakout | Breakout mode: score by weighted P&L across sigma-multiples of the | |
| --breakout-target | Override sigma-scaled scoring with a SINGLE fixed-pct target | |
| --stop-loss-pct | Score by reward / MTM-loss-at-stop instead of reward / structural-ML. | |
| --yolo | YOLO mode: widened OTM ranges (LC 95-300%% of stock, SP 30-130%%) and | |
| --yolo-cap | Override LC max strike multiplier in YOLO mode (default: | YOLO_LC_MAX_STRIKE_PCT_DEFAU |
| --anchor | Anchor all comparisons to a specific chain. Without LABEL: use | |
| --all | Run NORMAL + BREAKOUT + YOLO in one go and generate a single combined |
Output Location
runs/leaps/{TICKER}/latest.html
runs/leaps/{TICKER}/{TIMESTAMP}.html
runs/leaps/{TICKER}/audit_{TIMESTAMP}.json
Covered Call Scanner
cc_scanner.py β ~3070 lines
Sigma-band scoring for CC strikes above safe strike. IER (Income Efficiency Ratio) ranking. Single ticker or batch portfolio scan.
Common Usage
Single ticker with safe strike
python3 cc_scanner.py NVDA 480 --contracts 10
Batch portfolio scan from CSV
python3 cc_scanner.py --csv positions.csv --parallel 4
Reload previous scan (no IBKR)
python3 cc_scanner.py --from-scan ~/fortress/runs/CSVs/cc_scan_data.csv
Drawdown mode (tighter delta cap 0.25)
python3 cc_scanner.py GLD 165 --contracts 20 --drawdown-mode
Key Flags
| Flag | Description | Default |
|---|---|---|
| ticker | Stock ticker symbol (single-ticker mode) | |
| safe_strike | Safe Strike of the fortress (single-ticker mode) | |
| --csv | Path to CSV position file for batch/portfolio scan (requires IBKR) | |
| --from-scan | Path to previously exported scan CSV (no IBKR needed, dashboards only) | |
| --output-dir | Output directory for all files (default: ./outputs) | ./outputs |
| --contracts | Number of contracts (single-ticker mode, default: 10) | 10 |
| --max-delta | Maximum delta filter (default: {MAX_DELTA}) | MAX_DELTA |
| --max-dte | Maximum DTE to scan (default: from CSV per-ticker, or {MAX_DTE} in single-ticker mode) | |
| --min-dte | Minimum DTE to scan (default: from CSV per-ticker, or {MIN_DTE} in single-ticker mode) | |
| --host | IBKR TWS host (default: {DEFAULT_HOST}) | DEFAULT_HOST |
| --port | IBKR port (default: auto-detect. Tries 4001, 4002, 7496, 7497) | DEFAULT_PORT |
| --client-id | IBKR client ID (default: {DEFAULT_CLIENT_ID}) | DEFAULT_CLIENT_ID |
| --drawdown-mode | Enable drawdown mode (tighter DTE preference) | |
| --no-browser | Do not auto-open dashboards in browser | |
| --output | Output HTML filepath (single-ticker mode only) | |
| --parallel | Number of parallel IBKR connections for batch mode (default: 4). | 4 |
| --tickers | Filter --csv to only these tickers (e.g. --tickers MSFT NVDA TSLA) | |
| --skip-cc-timing | Skip the automatic cc_timing.py refresh at start of run. |
Output Location
runs/cc_scanner/{TICKER}/latest.html β per ticker
runs/cc_scanner/cc_scan_PORTFOLIO.html β master view
runs/CSVs/cc_scan_data.csv β reusable scan data
Roll Calls Analyzer
roll_calls.py β ~3550 lines
Scans existing short calls for roll-up (threatened) and roll-down (decayed) opportunities. Sigma-only thresholds, no DTE gate.
Common Usage
Full portfolio scan (roll-up + roll-down)
python3 roll_calls.py --roll-up --roll-down
Specific tickers, defensive roll-up only
python3 roll_calls.py --tickers NVDA COIN --roll-up
Roll-down with custom sigma floor
python3 roll_calls.py --roll-down --min-sigma 0.70 --top-n 5
Ticker with contracts + safe strike override
python3 roll_calls.py --tickers MSTR:5:350 --roll-up --roll-down
With safe strike CSV + show debit rolls
python3 roll_calls.py --csv ss_overrides.csv --roll-up --show-debits
Key Flags
| Flag | Description | Default |
|---|---|---|
| --host | TWS host (default: {DEFAULT_HOST}) | DEFAULT_HOST |
| --port | TWS port (default: {DEFAULT_PORT}) | DEFAULT_PORT |
| --client-id | Client ID (default: {DEFAULT_CLIENT_ID}) | DEFAULT_CLIENT_ID |
| --max-dte | Max DTE for current positions to scan (default: {MAX_CURRENT_DTE}) | MAX_CURRENT_DTE |
| --sigma-roll | Sigma threshold for ROLL (default: {SIGMA_ROLL}) | SIGMA_ROLL |
| --sigma-threatened | Sigma threshold for THREATENED (default: {SIGMA_THREATENED}) | SIGMA_THREATENED |
| --sigma-watch | Sigma threshold for WATCH (default: {SIGMA_WATCH}) | SIGMA_WATCH |
| --delta-fallback | Delta fallback when IV unavailable (default: {DELTA_FALLBACK}) | DELTA_FALLBACK |
| --max-roll-dte | Max DTE for roll candidates (default: {MAX_ROLL_DTE}) | MAX_ROLL_DTE |
| --target-delta | Target max delta for rolls (default: {TARGET_DELTA}) | TARGET_DELTA |
| --top-n | Top N candidates per position (default: {TOP_N}) | TOP_N |
| --account | IBKR account ID (e.g., U1234567). If omitted, uses default account. | |
| --tickers | Ticker filter with optional contract count and safe strike. | |
| --roll-up | Scan for roll-up candidates (defensive, move strike higher). | |
| --roll-down | Scan SAFE positions (sigma >= sigma_watch, delta <= 0.15) | |
| --force | Force roll analysis for --tickers positions | |
| --show-debits | Show best debit rolls when credits are scarce (cheapest path to safety) | |
| --proactive | Fetch proactive roll candidates for WATCH/THREATENED positions | |
| --min-sigma | Minimum sigma floor for roll-down targets (default: {ROLLDOWN_MIN_SIGMA}) | ROLLDOWN_MIN_SIGMA |
| --json | Export all roll data to JSON at this path (e.g., --json rolls.json). | |
| --html | Write HTML dashboard to this path (e.g., --html rolls.html). | |
| --csv | CSV with safe strikes per ticker (cols: TICKER, SS). | |
| --parallel | Number of parallel IBKR connections for roll analysis | 4 |
| --debug | Print detailed chain diagnostics for roll expiration discovery |
Output Location
runs/rolls/{TICKER}/latest.html
runs/rolls/PORTFOLIO/latest.html β full scan
CC Check
cc_check.py β ~390 lines
Reads safe_strike_list.csv, scans all IBKR accounts, and reports missing or partial covered call coverage.
Common Usage
Default scan (all accounts, safe_strike_list.csv)
python3 cc_check.py
Custom CSV
python3 cc_check.py --csv my_list.csv
Specific account only
python3 cc_check.py --account U1234567
Specific port
python3 cc_check.py --port 4001
Key Flags
Output Location
runs/cc_check/PORTFOLIO/latest.html
deploy/cc_check/PORTFOLIO.html β CF staged
Fortress Rebuild (Lifecycle Manager)
fortress_rebuild.py β ~3100 lines
Read-only lifecycle analyzer. Scans every fortress position across all IBKR accounts and recommends one action per fortress: SKIP, WAIT, ROLL, UNCAP, or REBUILD. Surfaces ride-to-expiry math (stock flat vs stock at CC strike), proactive roll candidates, and stranded-WAIT escalations. Routes all IBKR fetches through module_ibkr_fetch for identical reliability and logging (FROZENβDELAYEDβSNAP cascade, OI backfill, deep-ITM historical fallback).
Common Usage
Scan every fortress across every account
python3 fortress_rebuild.py
Bind to active_fortresses.csv (authoritative Entry / Safe Strike / Net Debit)
python3 fortress_rebuild.py --csv
Filter to specific tickers
python3 fortress_rebuild.py --tickers COIN,MSTR,IREN
Horizon cutoff β only fortresses with HP expiring by date; CC scan window tightens to match
python3 fortress_rebuild.py --expiry 2026-09-30
Single account
python3 fortress_rebuild.py --account U18827291
Fast mode β skip proactive roll fetches (useful for triage on slow IBKR)
python3 fortress_rebuild.py --no-rolls
Re-render from cached scan (no IBKR) β iterate on decision logic offline
python3 fortress_rebuild.py --cached
Decisions Produced
SKIP — structurally safe, no action needed.
WAIT — margin OK but borderline; monitor. Borderline variants show theta/trip-wire narrative.
WAIT (MARGINAL) — sigma is thin; roll candidates fetched proactively to find an escape.
ROLL CC — concrete roll candidate identified with credit, new sigma, and survival.
UNCAP — close the short call (strike capped, no forward roll viable).
REBUILD — structural damage; suggests going to leap_builder or fortress_repair.
WAIT — margin OK but borderline; monitor. Borderline variants show theta/trip-wire narrative.
WAIT (MARGINAL) — sigma is thin; roll candidates fetched proactively to find an escape.
ROLL CC — concrete roll candidate identified with credit, new sigma, and survival.
UNCAP — close the short call (strike capped, no forward roll viable).
REBUILD — structural damage; suggests going to leap_builder or fortress_repair.
Ride-to-Expiry Math
Every decision shows the "do nothing" baseline as explicit P/L:
CLOSE P/L — close fortress now at market mids.
STOCK FLAT — hold through CC expiry, stock unchanged. CC extrinsic decays to zero.
STOCK @ $strike — hold through CC expiry, stock rallies to cap. Adds fortress gain using full synthetic delta (LC long + SP short − HP long).
CLOSE P/L — close fortress now at market mids.
STOCK FLAT — hold through CC expiry, stock unchanged. CC extrinsic decays to zero.
STOCK @ $strike — hold through CC expiry, stock rallies to cap. Adds fortress gain using full synthetic delta (LC long + SP short − HP long).
Key Flags
| Flag | Description | Default |
|---|---|---|
| --host | TWS host | DEFAULT_HOST |
| --port | TWS port (default 7496) | DEFAULT_PORT |
| --client-id | IBKR clientId | DEFAULT_CLIENT_ID |
| --account | Single account to scan (default: all managed) | |
| --tickers | Ticker filter. Space-separated or comma-separated | |
| --expiry | Horizon cutoff date. (1) Hedge-put (HP): only show fortresses | |
| --csv | Use active_fortresses.csv as structural authority (ticker β | |
| --cached | Reuse cached scan data (skip IBKR) | |
| --no-rolls | Skip roll-chain fetches (faster) | |
| --get-cc-timing | Run cc_timing.py first to refresh the weekly-gate | |
| --cc-suggest | Append a section at the bottom of the dashboard | |
| --cc-suggest-max-dte | Max DTE for CC suggestions | CC_SUGGEST_MAX_DTE_DEFAULT |
| --cc-suggest-scope | Which fortresses to include: BOTH (default), | CC_SUGGEST_SCOPE_BOTH |
| --cc-suggest-max-rows | Optional explicit cap on candidate rows per expiry. | |
| --json | Also write raw JSON to this path | |
| --html | Also write HTML to this explicit path (OutputManager always runs) |
Output Location
runs/rebuild/{TICKER_LIST}/latest.html
deploy/rebuild/{TICKER_LIST}.html β CF staged
FIGHT Income Recovery
fortress_fight.py β ~2320 lines
Aggressive drawdown recovery via near-ATM short-dated calls. P&L curves at 8 price points, gap-up scenarios, income target tracking.
Common Usage
From fortress_results.json (most common)
python3 fortress_fight.py --from-results ~/fortress/runs/fortress/NVDA/fortress_results.json
Manual ticker + position detail
python3 fortress_fight.py --ticker NVDA:10:480:20260620 --fight-dte 7 --fight-otm 0.01
Multiple tickers from results
python3 fortress_fight.py --from-results fortress_results.json --tickers NVDA GLD COIN
Custom gap-up + income targets
python3 fortress_fight.py --ticker MSTR:5:350:20270117 --gap-pct 0.15 --targets 0.25 0.50 0.75 1.00
Key Flags
| Flag | Description | Default |
|---|---|---|
| csv_file | Chain data CSV (skips live chain fetch, still reads IBKR portfolio) | |
| --tickers | Ticker symbols. Space-separated or comma-separated | |
| --csv | Path to active_fortresses.csv (ticker β contracts, | |
| --legs | Optional leg detail (e.g. GLD:HP:410:20260630:7.214). Repeatable. | |
| --from-results | Read positions from fortress_results.json | |
| --host | IBKR TWS host (default: 127.0.0.1) | 127.0.0.1 |
| --port | IBKR port (default: auto-detect. Tries 4001, 4002, 7496, 7497) | 0 |
| --client-id | IBKR API client ID (default: 99). | 99 |
| --account | IBKR account ID (e.g. U1234567). | |
| --parallel | Parallel IBKR connections (default: 4) | 4 |
| --fight-otm | OTM%% for FIGHT CCs (default: {FIGHT_OTM_DEFAULT} = 1%%) | FIGHT_OTM_DEFAULT |
| --fight-dte | Target DTE for FIGHT CCs (default: {FIGHT_DTE_DEFAULT}) | FIGHT_DTE_DEFAULT |
| --expiry | HP (hedge put) expiry date. Accepts: 20260630, 30-Jun-2026, | |
| --targets | Income recovery targets as fractions (default: 0.35 0.70) | TARGETS_DEFAULT |
| --gap-pct | Gap-up scenario for risk calc (default: {GAP_PCT_DEFAULT} = 10%%) | GAP_PCT_DEFAULT |
| --html | HTML output path (default: fight_TICKER_TIMESTAMP.html) | |
| --no-html | Suppress HTML output entirely | |
| --json | JSON output path | |
| --publish | Stage and deploy HTML to Cloudflare Pages directory | |
| --notify | Push notification via ntfy.sh when done | |
| --force | Show roll decisions for ALL current CCs regardless of sigma | |
| --roi | Override annual ROI on ML for normal income ref | |
| --nd | Original entry ND per share (immutable, from trade creation). |
Output Location
runs/fight/{TICKER}/latest.html
runs/fight/{TICKER}/{TIMESTAMP}.html
Fortress Repair Analyzer
fortress_repair.py β ~2800 lines
Analyzes SP roll-down paths to lower the safe strike. Recommends HP repairs with payback analysis. Post-repair CC sustainability included.
Common Usage
Analyze specific tickers
python3 fortress_repair.py NVDA MSTR COIN
All fortress positions in portfolio
python3 fortress_repair.py --all
Filter by HP expiry, limit payback period
python3 fortress_repair.py --all --expiry 2026-06 --max-payback 0.5
With CC income override
python3 fortress_repair.py XLE --cc-income 0.45 --hp-min-dte 45 --hp-max-dte 90
Key Flags
| Flag | Description | Default |
|---|---|---|
| tickers | Ticker(s) to analyze (e.g. IREN IWM TSLA) | |
| --all | Analyze all fortress positions in portfolio | |
| --expiry | Filter to positions with HP expiring by this date (YYYY-MM or YYYYMMDD). | |
| --hp-min-dte | Min DTE for HP candidates (default: {HP_MIN_DTE}). | HP_MIN_DTE |
| --hp-max-dte | Max DTE for HP candidates (default: {HP_MAX_DTE}) | HP_MAX_DTE |
| --gap-mult | Max ratio of new_gap vs current gap (default: 2.0). | 2.0 |
| --price-multiplier | Add pick_score ROI component at Nx current stock price. | 0 |
| --max-payback | Max payback period in years for repair candidates (default: 1.0). | 1.0 |
| --cc-income | Monthly CC income per share override (e.g., 4.00). | 0 |
| --maint-roll-dte | DTE threshold for healthy-fortress HP maintenance roll | MAINT_ROLL_DTE |
| --maint-cost-cap | Max ratio of new HP annual cost vs CC annual income for | MAINT_COST_CAP |
| --no-maint | Skip the maintenance-roll pass on healthy fortresses. | |
| --account | Limit scan to this account ID. Default scans ALL | |
| --positions | CSV with actual position data (overrides IBKR avg_cost). | |
| --json | Export to JSON file | |
| --html | Export HTML dashboard | |
| --csv | CSV with safe strikes / ND / contracts / leg strikes | DEFAULT |
| --nd | Net Debit per share override (e.g., 16.0). | 0 |
Output Location
runs/repair/{TICKER}/latest.html
runs/repair/{TICKER}_{TICKER2}/latest.html β multi-ticker
Repair Trades Finder
repair_trades.py β ~3990 lines
Finds concrete 6-leg BAG repair trades (close 3 + open 3) with real IBKR prices. Exhaustive 1k-2k combo search, TIMS margin enrichment, P&L curves.
Common Usage
Basic repair analysis
python3 repair_trades.py MSTR
Specify expiry + contracts
python3 repair_trades.py COIN --expiry 20270117 --contracts 5
With IBKR margin check + CC overlay
python3 repair_trades.py BMNR --margin --cc --gap-mult 3.0
Crypto miner: 3x price projection + FIGHT panel
python3 repair_trades.py MARA --price-multiplier 3 --fight --cc
Custom DTE range for target LEAPS
python3 repair_trades.py NVDA --min-target-dte 400 --max-target-dte 800
Key Flags
| Flag | Description | Default |
|---|---|---|
| ticker | Ticker to analyze (e.g. MARA) | |
| --expiry | Current position expiry to match (YYYYMMDD or 18-sep-2026). | |
| --contracts | Override contract count (e.g. 200 for 200 contracts = 20000 shares) | 0 |
| --lc | Select fortress structure by LC strike (e.g. --lc 60). | 0 |
| --html | HTML output path (default: repair_<TICKER>_<timestamp>.html) | |
| --audit | Audit log JSON path (default: audit_<TICKER>_<timestamp>.json) | |
| --gap-mult | Max gap multiplier vs current gap (default: {SA_GAP_MULT}x) | SA_GAP_MULT |
| --margin | Run IBKR whatIf margin checks on top candidates (requires write access) | |
| --min-target-dte | Minimum DTE for target LEAPS expiries (default: 365) | 365 |
| --max-target-dte | Maximum DTE for target LEAPS expiries (default: 1100) | 1100 |
| --price-multiplier | Add P&L projection at Nx current price (e.g., 10 for 10x). | 0 |
| --cc | Add CC income overlay to lens picks (scans DTE 5-50 call chains) | |
| --fight | Add FIGHT income panel: near-ATM short-dated CCs for income | |
| --nd | Override net debit per share (all-in cost basis). | 0 |
| --no-roll | Skip roll candidates entirely. Only restructure within current expiry. | |
| --max-candidates | Cap total candidates after merge (default 250000). | 250000 |
| --pnl | P&L curve only. Connects to IBKR, reads position, | |
| --pnl-max | Max stock price for P&L curve (default: 5x current price) | 0 |
Output Location
runs/repair_trades/{TICKER}/latest.html
runs/repair_trades/{TICKER}/audit_{TIMESTAMP}.json
Stock Researcher
stock_researcher.py β ~3040 lines
4-pillar quantitative scoring: Fundamentals (40%) + Technicals (15%) + Fortress Fit (30%) + Valuation (15%). AI narrative via Claude API. Hard gates apply.
Common Usage
Research single ticker
python3 stock_researcher.py NVDA
Batch research (multiple tickers)
python3 stock_researcher.py MSTR COIN BMNR RKLB HOOD AMD SOFI NVDA PLTR MU
Custom investment horizon
python3 stock_researcher.py GOOG --horizon "2-3 years"
No IBKR (yfinance IV only)
python3 stock_researcher.py MU AMD PLTR --no-ibkr
Scoring Pillars
| Pillar | Weight | Key Metrics |
|---|---|---|
| Fundamentals | 40% | Revenue growth, margins, FCF, debt |
| Fortress Fit | 30% | IV, liquidity, options chain depth, trend alignment |
| Valuation | 15% | P/E, P/S, EV/EBITDA vs peers |
| Technicals | 15% | Momentum, moving averages, RSI |
Key Flags
| Flag | Description | Default |
|---|---|---|
| tickers | Stock tickers | |
| --horizon | Investment horizon (default: '1-2 years | 1-2 years |
| --output | Output HTML path | |
| --api-key | Anthropic API key (or ANTHROPIC_API_KEY env) | |
| --no-ibkr | Skip IBKR, yfinance IV only | |
| --json | Also dump raw data as JSON alongside HTML |
Output Location
runs/research/{TICKER}/latest.html
runs/research/{TICKER1}_{TICKER2}/latest.html β multi
Portfolio Dashboard
fortress_portfolio.py β ~1360 lines
Reads live IBKR positions, identifies all fortress structures, computes live metrics (SS, gap, income, survival). Snapshot of the full book.
Common Usage
Full portfolio snapshot
python3 fortress_portfolio.py --all
Specific tickers only
python3 fortress_portfolio.py NVDA MSTR COIN GLD
Filter by LEAPS expiry month
python3 fortress_portfolio.py --all --expiry 2027-01
With average cost override from CSV
python3 fortress_portfolio.py --all --positions ~/my_positions.csv
Key Flags
| Flag | Description | Default |
|---|---|---|
| tickers | Ticker(s) to include (e.g. IREN IWM TSLA) | |
| --all | Include all fortress positions in portfolio | |
| --expiry | Filter to positions with LEAPS expiring by this date (YYYY-MM or YYYYMMDD) | |
| --account | Account ID(s) to scan. Comma-separated or space-separated. | |
| --positions | CSV with actual position data (overrides IBKR avg_cost). | |
| --html | Output HTML file path | |
| --json | Export to JSON file |
Output Location
runs/fortress/PORTFOLIO/latest.html
runs/fortress/PORTFOLIO/{TIMESTAMP}.html
Chain Exporter
fortress_export.py β ~1180 lines
Exports full option chains (LEAPS + Hedge + Income) with Greeks to CSV. Used to feed fortress_v26.py in offline mode. Parallel workers, FROZEN/DELAYED fallbacks.
Common Usage
Export single ticker (all strikes)
python3 fortress_export.py NVDA
Export multiple tickers in parallel
python3 fortress_export.py MSTR COIN GLD XLE --parallel 4
Short-term mode (280-450d LEAPS)
python3 fortress_export.py NVDA --short-term
Custom DTE ranges for each chain type
python3 fortress_export.py SPY QQQ --leaps-dte 365 900 --hedge-dte 45 90 --income-dte 7 30
Then feed directly to optimizer
python3 fortress_v26.py ~/fortress/runs/CSVs/NVDA_20260407.csv --contracts 10
Key Flags
| Flag | Description | Default |
|---|---|---|
| tickers | One or more ticker symbols | |
| --host | TWS host | DEFAULT_HOST |
| --port | TWS port | DEFAULT_PORT |
| --client-id | Client ID | DEFAULT_CLIENT_ID |
| --output | Custom output CSV path | |
| --width | Strikes per chain, 0=ALL (default: {STRIKE_WIDTH}) | STRIKE_WIDTH |
| --short-term | Short-term mode: LEAPS 180-450d (default: 180+) | False |
| --leaps-dte | Override LEAPS DTE range (e.g. --leaps-dte 180 365) | |
| --hedge-dte | Override hedge DTE range (default: {HEDGE_DTE_MIN} {HEDGE_DTE_MAX}) | |
| --income-dte | Override income DTE range (default: {INCOME_DTE_MIN} {INCOME_DTE_MAX}) | |
| --parallel | Number of parallel IBKR connections (default: 1). Each worker | 4 |
Output Location
runs/CSVs/{TICKER}_{TIMESTAMP}.csv
Columns: ticker, type (LEAPS/HEDGE/INCOME),
strike, expiry, bid, ask, iv, delta, gamma,
theta, vega, volume, open_interest
Typical Workflow
Step 1 β Export chains during market hours
Step 2 β Run optimizer on saved CSV (no IBKR needed)
python3 fortress_export.py NVDA MSTRStep 2 β Run optimizer on saved CSV (no IBKR needed)
python3 fortress_v26.py ~/fortress/runs/CSVs/NVDA_*.csv
CSV-only output
This tool exports option chains to CSV only.
Feed the CSV to
fortress_v26.py for the dashboard.Sample CSV path:
runs/CSVs/NVDA_20260407_143022.csvGS Put Seller
gs_put_seller.py β ~1200 lines
Goldman Sachs "Art of Put Selling" screener. Finds optimal puts by FCF yield targets (1x / 2x / 3x monthly FCF). Specific tickers or SPX/QQQ/IWM discovery mode.
Common Usage
Specific tickers
python3 gs_put_seller.py --tickers MSFT AAPL NVDA GOOG
Discovery mode (screen index constituents)
python3 gs_put_seller.py --scan --top 10
No IBKR, specific expiry
python3 gs_put_seller.py --tickers QQQ SPY --no-ibkr --expiry 20260515
Capital sizing + force rescan
python3 gs_put_seller.py --scan --capital 500000 --collateral-pct 25 --rescan
Key Flags
| Flag | Description | Default |
|---|---|---|
| --tickers | Space-separated ticker symbols | |
| --scan | Discovery mode: screen SPX, QQQ, IWM constituents | False |
| --top | Top N stocks per index in discovery mode (default: 10) | 10 |
| --expiry | Target expiration (YYYYMMDD). Auto-selects nearest monthly 20-45 DTE if omitted | |
| --capital | Total portfolio capital for position sizing | |
| --collateral-pct | Collateral %% per put (100=fully collateralized, default: 100) | 100 |
| --port | TWS port (default: 0 = auto-detect TWS/Gateway) | DEFAULT_PORT |
| --no-ibkr | Use yfinance instead of IBKR for options data | False |
| --min-oi | Minimum open interest filter (default: 100) | 100 |
| --max-spread-pct | Maximum bid-ask spread as %% of bid (default: 15.0) | 15.0 |
| --output | Output directory for HTML report | str(Path.home( |
| --rescan | Force fresh discovery scan, ignore cache | False |
Output Location
deploy/gs_putseller/{TICKER1}_{TICKER2}.html
(also staged to deploy/ for CF Pages)