Skip to main content

An automated options wheel trading strategy.

Project description

wheel-it

Automated options wheel strategy bot. Sell cash-secured puts, handle assignments, sell covered calls, collect premiums — repeat.


Install

pip install wheel-it

Quick Start

  1. Set up your API keys — create a .env file (or export the variables):

    ALPACA_API_KEY=your_public_key
    ALPACA_SECRET_KEY=your_private_key
    IS_PAPER=true
    FINNHUB_API_KEY=your_finnhub_key
    

    Get Alpaca keys at alpaca.markets. Get a free Finnhub key at finnhub.io/register.

  2. Choose your stocks — edit config/symbol_list.txt with one ticker per line. Pick stocks you'd be comfortable holding long-term.

  3. Run it:

    wheelit
    

    That's it. The bot will check your positions, sell covered calls on any assigned stock, and sell new puts on your symbol list within your buying power.

CLI Options

wheelit run --fresh-start       # liquidate all positions first (recommended for first run)
wheelit run --screen            # run stock screener before strategy
wheelit run --max-risk 100000   # set total capital budget (default: from config/preset)
wheelit run --strat-log         # enable JSON strategy logging
wheelit run --log-level DEBUG   # set log verbosity
wheelit run --log-to-file       # save logs to file

Interactive TUI

Every CLI command has an interactive TUI mode powered by Trogon. Configure options visually in a fullscreen form:

wheelit tui
run-screener tui
run-put-screener tui
run-call-screener tui

Use Ctrl+R to execute, Ctrl+C to quit.


Stock Screener

Find wheel-suitable stocks using Finnhub fundamentals and Alpaca technicals:

run-screener run                          # default (moderate) preset
run-screener run --preset conservative    # large-cap, low debt
run-screener run --preset aggressive      # small-cap OK
run-screener run --top-n 20              # only screen the top 20 worst performers
run-screener run --verbose               # show per-filter breakdown
run-screener run --update-symbols        # export results to symbol_list.txt

Recommended Commands

# Best for free-tier API accounts (Alpaca + Finnhub)
run-screener run --preset moderate --top-n 15

# Full scan if you have paid API access
run-screener run --preset moderate

# Screen and auto-update your symbol list
run-screener run --preset moderate --top-n 20 --update-symbols

Using --top-n

The --top-n N flag limits screening to the N worst-performing stocks from the initial technical scan. This is important if you're on free API tiers — Finnhub and Alpaca free plans have strict rate limits, and screening hundreds of symbols will hit those limits quickly.

How it works:

  1. Stage 1 fetches technicals for all candidates (cheap, single API call per symbol)
  2. Survivors are ranked by recent performance (worst performers first — these tend to have the juiciest put premiums)
  3. --top-n cuts the list to the top N before hitting the rate-limited Finnhub and options chain APIs in Stages 2-4

This keeps API usage low while focusing on the most promising wheel candidates. Start with --top-n 15 on free accounts and increase as your rate limits allow.

Presets

Category Conservative Moderate Aggressive
Max Risk $50K $80K $120K
Market Cap Min $10B $2B $500M
Debt/Equity Max 0.5 1.5 3.0
Avg Volume Min 1M 500K 200K
HV Percentile Min 50 30 20
Earnings Exclusion 21 days 14 days 7 days
DTE Min 21 14 7
DTE Max 45 60 60
Options OI Min 500 100 50
Options Spread Max 5% 10% 20%
Sector Exclusions Biotech, Cannabis, O&G Cannabis None

Custom overrides go in config/screener.yaml. Preset files are in config/presets/.

Weekly DTE Example

To target weekly expirations (7 DTE), add to config/screener.yaml:

options:
  dte_min: 7
  dte_max: 8

Or use the aggressive preset which allows 7+ DTE by default:

wheelit run --screen --top-n 10 --max-risk 5000

Pipeline

4-stage filtering in cheap-first order:

  1. Technicals (Alpaca) — price range, volume, RSI, SMA(200), HV percentile
  2. Earnings (Finnhub) — exclude stocks with upcoming earnings
  3. Fundamentals (Finnhub) — market cap, debt/equity, net margin, sales growth, sector
  4. Options Chain (Alpaca) — open interest, bid/ask spread on nearest ATM put

Survivors are scored by wheel suitability (capital efficiency 45%, volatility 35%, fundamentals 20%).


Put & Call Screeners

Explore specific option opportunities:

run-put-screener run AAPL MSFT GOOG --buying-power 50000
run-put-screener run AAPL --buying-power 20000 --preset conservative

run-call-screener run AAPL --cost-basis 175.00
run-call-screener run AAPL --cost-basis 175.00 --preset conservative

The call screener enforces strike >= cost basis so you never sell below your entry. Both rank by annualized return.


Automating

Run wheelit on a schedule to keep the wheel turning. Example cron (Mac/Linux) — runs at 10 AM, 1 PM, and 3:30 PM ET on weekdays:

0 10 * * 1-5 /path/to/wheelit >> /path/to/logs/10am.log 2>&1
0 13 * * 1-5 /path/to/wheelit >> /path/to/logs/1pm.log 2>&1
30 15 * * 1-5 /path/to/wheelit >> /path/to/logs/330pm.log 2>&1

Find your install path with which wheelit.


Build from Source

  1. Clone the repository:

    git clone https://github.com/vahagn-madatyan/wheel-it.git
    cd wheel-it
    
  2. Create a virtual environment using uv:

    uv venv
    source .venv/bin/activate  # or .venv\Scripts\activate on Windows
    
  3. Install in editable mode:

    uv pip install -e .
    
  4. Configure .env and config/symbol_list.txt as described above.

  5. Run tests:

    python -m pytest tests/ -q
    

Tuning

  • config/params.py — strategy constants (buying power limits, delta range, scoring thresholds)
  • config/presets/ — screener preset YAML files
  • config/screener.yaml — custom screener overrides

How It Works

  1. Sell cash-secured puts on stocks you wouldn't mind owning
  2. If assigned, buy the stock
  3. Sell covered calls on the shares you hold
  4. Collect premiums until the stock gets called away
  5. Repeat

Strategy Details

  • Stock filtering — only trades symbols where 100 shares fit within buying power
  • OTM enforcement — puts must have strike < current stock price (no ITM or ATM)
  • Option filtering — delta range, open interest, yield, bid/ask spread
  • Extrinsic ranking — annualized return uses time value (extrinsic premium) only, not total premium, so ITM contracts can't inflate their ranking with intrinsic value
  • Diversification — one contract per underlying symbol
  • Call strike floor — covered calls enforce strike >= cost basis

Important Notes

  • This strategy assumes full control of the account. Start with a clean account or use --fresh-start.
  • One contract per symbol to simplify risk management.
  • Always double-check live trades — no system is completely hands-off.
  • Start with paper trading (IS_PAPER=true) before using real money.

Attribution

This project was inspired by and forked from Alpaca's options-wheel repository. Read their article on the wheel strategy: Options Wheel Strategy — Alpaca Learn.


Disclosures

Options trading is not suitable for all investors due to its inherent high risk, which can potentially result in significant losses. Please read Characteristics and Risks of Standardized Options before investing in options.

The Paper Trading API is offered by AlpacaDB, Inc. and does not require real money or permit a user to transact in real securities in the market. Providing use of the Paper Trading API is not an offer or solicitation to buy or sell securities, securities derivative or futures products of any kind, or any type of trading or investment advice, recommendation or strategy, given or in any manner endorsed by AlpacaDB, Inc. or any AlpacaDB, Inc. affiliate and the information made available through the Paper Trading API is not an offer or solicitation of any kind in any jurisdiction where AlpacaDB, Inc. or any AlpacaDB, Inc. affiliate (collectively, "Alpaca") is not authorized to do business.

All investments involve risk, and the past performance of a security, or financial product does not guarantee future results or returns. There is no guarantee that any investment strategy will achieve its objectives. Please note that diversification does not ensure a profit, or protect against loss. There is always the potential of losing money when you invest in securities, or other financial products. Investors should consider their investment objectives and risks carefully before investing.

Securities brokerage services are provided by Alpaca Securities LLC ("Alpaca Securities"), member FINRA/SIPC, a wholly-owned subsidiary of AlpacaDB, Inc. Technology and services are offered by AlpacaDB, Inc.

This is not an offer, solicitation of an offer, or advice to buy or sell securities or open a brokerage account in any jurisdiction where Alpaca Securities is not registered or licensed, as applicable.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wheel_it-0.4.0.tar.gz (115.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wheel_it-0.4.0-py3-none-any.whl (137.3 kB view details)

Uploaded Python 3

File details

Details for the file wheel_it-0.4.0.tar.gz.

File metadata

  • Download URL: wheel_it-0.4.0.tar.gz
  • Upload date:
  • Size: 115.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for wheel_it-0.4.0.tar.gz
Algorithm Hash digest
SHA256 ab738221a366aab0207abeaa26868fc4b3cded7e1b50427d74d540ed20ad7b27
MD5 64137e7ee3d8a5a8d6c85ce9678717a7
BLAKE2b-256 14374f433aac0a6260a2b33586cc9090332ff937196de27b4d2ffe7ccc787e3c

See more details on using hashes here.

Provenance

The following attestation bundles were made for wheel_it-0.4.0.tar.gz:

Publisher: pypi-publish.yml on vahagn-madatyan/wheel-it

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file wheel_it-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: wheel_it-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 137.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for wheel_it-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9dfc6bc272c7a2d9707b57efe1456c1a2b868eab2185df8730d870533feebc4f
MD5 c261896a475ef3625a1b9ca25b695728
BLAKE2b-256 8a4ebef87e285f6b8a8a460b435377f302b206a8521843d3e81ae10f18a7aa5f

See more details on using hashes here.

Provenance

The following attestation bundles were made for wheel_it-0.4.0-py3-none-any.whl:

Publisher: pypi-publish.yml on vahagn-madatyan/wheel-it

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page