feat: ib-pmcc-bot — operational PMCC bot (scan, open, manage)#76
Open
tradam-m wants to merge 2 commits into
Open
feat: ib-pmcc-bot — operational PMCC bot (scan, open, manage)#76tradam-m wants to merge 2 commits into
tradam-m wants to merge 2 commits into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds an operational PMCC (Poor Man’s Covered Call) bot and extends the IB option-chain tooling to support futures options (FOP) with model Greeks, plus accompanying CLI/docs/tests.
Changes:
- Introduce
pmcc_botorchestration (scan → select via margin gate → place combo orders; manage shorts via decay trigger). - Add futures/FOP helpers and enhance option-chain extraction (asset-type autodetect, greeks, multiplier).
- Add unit tests and CLI skill wrappers; bump package version.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
src/trading_skills/broker/pmcc_bot.py |
New operational PMCC bot with pure selection/plan logic + IBKR order/position I/O |
src/trading_skills/broker/options.py |
Add futures/FOP support, asset-type resolution, Greeks extraction, and unified quote-row builder |
src/trading_skills/broker/futures.py |
New helpers to detect futures exchange and resolve FOP contracts via contract details |
tests/test_broker_pmcc_bot.py |
Unit tests for PMCC bot pure functions (selection, tagging, decay trigger, plan builder) |
tests/test_broker_futures.py |
Unit tests for futures exchange selection and options greeks/quote extraction helpers |
.claude/skills/ib-pmcc-bot/scripts/bot.py |
CLI wrapper for running the PMCC bot (dry-run default) |
.claude/skills/ib-pmcc-bot/SKILL.md |
Skill documentation for PMCC bot operation and safety model |
.claude/skills/ib-option-chain/scripts/options.py |
Add --sec-type flag passthrough to force stock vs future resolution |
.claude/skills/ib-option-chain/SKILL.md |
Update docs to reflect futures/FOP support + greeks/multiplier fields |
pyproject.toml |
Bump project version to 0.10.0 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| acct = account or (managed[0] if managed else None) | ||
|
|
||
| funds = await _available_funds(ib, acct) if acct else {} | ||
| available = funds.get("available_funds") or funds.get("excess_liquidity") or 0.0 |
|
|
||
| quote = await _fetch_single_option_quote(ib, symbol, short["strike"], short["expiry"], "C") | ||
| current_price = get_option_price(quote or {}, price_mode) | ||
| decay = short_decay_pct(premium_received, current_price or 0) |
Comment on lines
+368
to
+372
| "premium_received": round(premium_received, 2), | ||
| "current_short_price": round(current_price, 2) if current_price else None, | ||
| "decay_pct": round(decay * 100, 1), | ||
| "action": "close_and_reroll" if close else "hold", | ||
| "limit_price": round(current_price, 2) if current_price else None, |
| """ | ||
| try: | ||
| async with ib_connection(port, CLIENT_IDS["pmcc_advisor"]) as ib: | ||
| ib.reqMarketDataType(4) |
|
|
||
| return { | ||
| "generated_at": generated_at_str(), | ||
| "data_delay": "real-time", |
Comment on lines
+205
to
+208
| bid = t.bid if t.bid and t.bid > 0 else None | ||
| ask = t.ask if t.ask and t.ask > 0 else None | ||
| last = t.last if t.last and t.last > 0 else None | ||
| volume = int(t.volume) if t.volume and t.volume >= 0 else None |
Comment on lines
+216
to
+220
| "impliedVolatility": ( | ||
| round(t.modelGreeks.impliedVol * 100, 2) | ||
| if t.modelGreeks and t.modelGreeks.impliedVol | ||
| else None | ||
| ), |
Comment on lines
+74
to
+80
| ib_logger = logging.getLogger("ib_async") | ||
| prev_level = ib_logger.level | ||
| ib_logger.setLevel(logging.CRITICAL) | ||
| try: | ||
| qualified = await ib.qualifyContractsAsync(stock) | ||
| finally: | ||
| ib_logger.setLevel(prev_level) |
Comment on lines
+62
to
+68
| resolved = [] | ||
| for strike in strikes: | ||
| base = FuturesOption(sym, expiry, strike, right, exchange=exchange) | ||
| try: | ||
| details = await ib.reqContractDetailsAsync(base) | ||
| except Exception: | ||
| details = [] |
| return greeks | ||
|
|
||
|
|
||
| async def _resolve_underlying(ib: IB, symbol: str, sec_type: str | None) -> tuple: |
Scans an equity universe for diagonal-call (PMCC) opportunities, opens the top-N that fit available funds as combo BAG orders, and actively manages its own shorts (buy-to-close + reroll once premium has decayed past a threshold). - Options only: long leg is always a long call, never a future. - Margin-gated entry against AvailableFunds; dedup skips held/pending symbols. - Orders tagged BOT_PMCC_* / BOT_CLOSE_*; manages only equity diagonals, so manual futures/stock positions are excluded by construction. - Dry-run by default; --execute places orders. Market-hours guard blocks off-hours fills on stale quotes. - Confirms order status before disconnect (orders placed then dropped on immediate disconnect otherwise). - 16 unit tests for margin gate, exit trigger, sizing, tagging. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
tradam-m
force-pushed
the
feat/pmcc-bot-operational
branch
from
June 12, 2026 09:36
d7c8cd3 to
7561534
Compare
Contributor
Author
|
Ready for review / merge.
Unrelated to #62 (that was time-dependent test rot in |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds ib-pmcc-bot, an operational PMCC bot that turns the existing PMCC scanner into an operator: it scans an equity universe for diagonal-call opportunities, opens the top-N that fit available funds as combo BAG orders, and actively manages its own shorts (buy-to-close + reroll once the premium has decayed past a threshold).
Behaviour
AvailableFunds(fallbackExcessLiquidity); candidates that don't fit are skipped with an explicit reason.BOT_PMCC_*/BOT_CLOSE_*); exit management touches only equity diagonal-call spreads, so manual futures/stock positions are excluded by construction.--executeplaces orders. Market-hours guard (is_trading_now) blocks off-hours fills on stale quotes.Files
src/trading_skills/broker/pmcc_bot.py— bot logic (pure/testable core + IBKR I/O).claude/skills/ib-pmcc-bot/— skill + CLI wrapper (dry-run default,--execute)tests/test_broker_pmcc_bot.py— 16 unit tests (margin gate, exit trigger, sizing, tagging)Testing
ruff check/formatclean.test_mcp_server.py::*_handles_no_connectiontests fail only when an IB Gateway is running locally during pytest (known environmental artifact); they pass in CI with no IB.🤖 Generated with Claude Code