Skip to content

feat(options-gps): autonomous execution — CLI trades options on Deribit/Aevo (closes #26)#42

Open
MkDev11 wants to merge 6 commits intoentrius:mainfrom
MkDev11:feature/issue-26-autonomous-execution
Open

feat(options-gps): autonomous execution — CLI trades options on Deribit/Aevo (closes #26)#42
MkDev11 wants to merge 6 commits intoentrius:mainfrom
MkDev11:feature/issue-26-autonomous-execution

Conversation

@MkDev11
Copy link
Contributor

@MkDev11 MkDev11 commented Mar 13, 2026

Summary

Options GPS can now autonomously trade options on Deribit and Aevo directly from the CLI. This adds a full execution engine with order placement, order lifecycle management (place → monitor → cancel), slippage protection, position sizing, and safety guardrails — transforming the tool from analysis-only to end-to-end autonomous execution.

Before: CLI showed recommended venue/price per leg but could not place orders. No --execute or Screen 5.

After: --dry-run simulates execution (no credentials needed); --execute best (or safer/upside) submits live orders to Deribit/Aevo. Each leg is auto-routed to its best venue. Orders are monitored with configurable timeout, protected by slippage limits, and partially-filled multi-leg strategies are automatically unwound on failure.

Related Issues

Closes #26

Type of Change

  • Bug fix
  • Improvement to existing tool
  • Documentation
  • Other (describe below)

What Changed

executor.py — New execution engine (719 lines)

Data model:

  • OrderRequest / OrderResult / ExecutionPlan / ExecutionReport dataclasses
  • OrderResult tracks timestamp (ISO 8601), slippage_pct, and latency_ms per fill
  • ExecutionPlan supports max_slippage_pct, timeout_seconds, quantity_override
  • ExecutionReport includes started_at, finished_at, cancelled_orders

Executors (abstract BaseExecutor with full order lifecycle):

  • DryRunExecutor — simulates fills from quote data; tracks orders for status/cancel
  • DeribitExecutor — POST + JSON-RPC 2.0 with OAuth token caching, USD↔BTC price conversion, live order book pricing, tick-size alignment
  • AevoExecutor — REST with HMAC-SHA256 signing (method + path + timestamp + body)

Order lifecycle: place_order()get_order_status()cancel_order() on all executors

Execution engine:

  • build_execution_plan() — auto-routes per leg via leg_divergences, builds exchange-specific instrument names (Deribit: BTC-27MAR26-71000-C, Aevo: BTC-71000-C), applies quantity override
  • validate_plan() — pre-flight checks (instruments, prices, quantities, actions)
  • execute_plan() — sequential execution with:
    • Order monitoring: polls get_order_status() until filled or timeout, then cancels
    • Slippage protection: rejects fills exceeding --max-slippage threshold
    • Auto-cancel on partial failure: cancels already-filled legs when a later leg fails
  • get_executor() factory — reads credentials from env vars, supports testnet

main.py — CLI integration

New flags:

Flag Purpose
--execute best|safer|upside Which strategy card to trade
--dry-run Simulate without placing real orders
--force Override no-trade guardrail for live execution
--exchange deribit|aevo Force all legs to one venue (default: auto-route)
--max-slippage N Max allowed slippage % per fill (0=off)
--quantity N Override contract quantity for all legs (0=default)
--timeout N Seconds to wait for order fill before cancel (0=fire-and-forget)
--screen none Skip analysis screens 1-4, show only execution (Screen 5)

Screen 5 (Execution): order plan display, live confirmation prompt, per-leg results with slippage/latency metrics, auto-cancelled orders, execution timestamps.

Decision log: execution block now includes started_at, finished_at, per-fill slippage_pct/latency_ms/timestamp, cancelled_orders, max_slippage_pct, timeout_seconds, quantity_override.

README.md — Updated documentation

  • Exchange integration architecture (Synth → pipeline → quotes → routing → execution → lifecycle → safety)
  • All CLI flags and env vars documented
  • Test coverage description updated

Testing

  • Tested against Synth API
  • Manually tested
  • Tests added/updated

Test breakdown

test_executor.py — 54 tests:

  • TestInstrumentNames (7) — Deribit/Aevo name builders, roundtrip parsing, edge cases
  • TestBuildPlan (6) — single/multi-leg, exchange override, aevo names, auto-route, estimated cost
  • TestValidatePlan (5) — valid plan, empty orders, zero price, zero quantity, empty instrument
  • TestDryRunExecutor (12) — authenticate, buy/sell fills, missing strike, no-match fallback, get_order_status, status not found, cancel_order, cancel not found, timestamp on result, slippage tracked
  • TestExecuteFlow (7) — single/multi-leg, net cost, auto-routing factory, summary message, report timestamps
  • TestGetExecutor (5) — dry-run, dry-run ignores exchange, missing creds (Deribit/Aevo), unknown exchange
  • TestSlippage (8) — buy worse/better, sell worse/better, zero expected, slippage protection rejects, slippage protection allows
  • TestQuantityOverride (3) — default quantity, override applied (single-leg), override applied (multi-leg)

test_executor_e2e.py — 8 tests:

  • Full pipeline → dry-run execution
  • Guardrail: refuse live when no-trade, allow with force, allow dry-run, allow when no guardrail
  • Multi-leg execution pipeline (spread → rank → build → dry-run → verify all legs + timestamps)
  • Non-crypto symbol skips execution (SPY returns no exchange quotes)
  • Slippage protection E2E (full pipeline with slippage guard → all pass)

Verify: python3 -m pytest tools/options-gps/tests/ -v177 passed (119 existing + 58 new).

Edge Cases Handled

# Scenario Behavior
E1 No API credentials get_executor raises with clear env var message
E2 Non-crypto symbol + execute Exit 1: "Execution only supported for crypto assets"
E3 No exchange quotes available Exit 1: "exchange data not available"
E4 Multi-leg partial failure Auto-cancel filled legs; report which were cancelled
E5 Instrument names per exchange Deribit: BTC-27MAR26-71000-C; Aevo: BTC-71000-C
E6 No-trade guardrail active Refuse live execution unless --force; dry-run always allowed
E7 Dry-run mode No HTTP calls to exchange; simulates from quote data
E8 Default CLI (no execute flags) Unchanged — analysis screens only
E9 Slippage exceeds threshold Order rejected + cancelled; partial fills unwound
E10 Order timeout Polls status; cancels if still open after deadline
E11 Negative sleep on monitor deadline Clamped to 0 — no ValueError crash
E12 Quantity override = 0 Uses strategy default leg quantities

Environment Variables (live execution)

Variable Purpose
DERIBIT_CLIENT_ID / DERIBIT_CLIENT_SECRET Deribit API credentials
DERIBIT_TESTNET=1 Use Deribit testnet
AEVO_API_KEY / AEVO_API_SECRET Aevo API credentials
AEVO_TESTNET=1 Use Aevo testnet

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Changes are documented (if applicable)

Demo Video

https://screenrec.com/share/KnbYFEMVvT

…ibit/Aevo (closes entrius#26)

- executor.py: Deribit via POST+JSON-RPC, Aevo HMAC, DryRun, auto-route per leg
- main.py: --execute best|safer|upside, --dry-run, --force, --exchange; Screen 5; guardrail refusal
- README: exchange integration architecture, Execution section, env vars
- 37 tests: instrument names, plan build/validate, dry-run, factory, guardrail, E2E
@MkDev11 MkDev11 force-pushed the feature/issue-26-autonomous-execution branch from d87e1b3 to b1eafb4 Compare March 13, 2026 17:38
@eureka928
Copy link
Contributor

eureka928 commented Mar 13, 2026

Hi @MkDev11 please leave gps part to me, please do not copy my approach from previous commit, this can be penalized...

@MkDev11
Copy link
Contributor Author

MkDev11 commented Mar 13, 2026

@eureka928 I implemented the issue using my own approach, not yours. Also, this is a public issue, not a private one, so anyone is free to work on it and open their own PRs.

@MkDev11
Copy link
Contributor Author

MkDev11 commented Mar 13, 2026

don’t make my PR messy. my approach is my own, and it doesn’t mean I used yours. I already spent enough time working on this issue.

- Deribit: use contracts not amount for options order size
- Retry transient errors (timeout, 5xx) in _deribit_rpc and AevoExecutor
- Add execution.testnet to decision log from env
- DeribitExecutor: cache token, skip re-auth for multi-leg same exchange
- Remove unreachable code in _deribit_rpc
@eureka928
Copy link
Contributor

don’t make my PR messy. my approach is my own, and it doesn’t mean I used yours. I already spent enough time working on this issue.

Okay, but just don't copy others... just use your own judgement

MkDev11 added 2 commits March 13, 2026 20:15
…ride, bug fixes

- Add get_order_status/cancel_order to all executors (DryRun, Deribit, Aevo)
- Add execution timestamps, slippage %, latency ms to OrderResult
- Add slippage protection (--max-slippage): reject fills exceeding threshold
- Add quantity override (--quantity): override contract count for all legs
- Add order monitoring (--timeout): poll until filled or cancel on timeout
- Add auto-cancel of filled legs on partial multi-leg failure
- Fix Aevo HMAC signing to include HTTP method + path in signature
- Fix quantity_override not applied during plan build (was set post-build)
- Fix _monitor_order negative sleep ValueError on deadline overrun
- Enhanced Screen 5 output with slippage/latency/timestamps
- Enhanced decision log JSON with per-fill metrics and cancelled orders
- Add 21 new tests: lifecycle, slippage, timestamps, quantity override,
  multi-leg E2E, non-crypto skip, slippage E2E (177 total, all passing)
- Update README with new CLI flags and test coverage
… valid expiry

- DeribitExecutor.place_order: use 'amount' param (not 'contracts') for options
- Add _get_index_price: fetch/cache underlying price for USD→BTC conversion
- Add _get_book_price: fetch live order book ask/bid with mark_price fallback
- Snap prices to tick size (0.0005) to avoid Deribit tick conformance rejection
- Convert BTC fill prices back to USD for pipeline consistency
- Update mock data expiry from 2026-02-26 to 2026-03-27 (valid on testnet)
- Update deribit_BTC.json instrument names to match (27MAR26)
- Verified: live testnet order placement, monitoring, timeout+cancel all working
- 177 tests passing
@MkDev11
Copy link
Contributor Author

MkDev11 commented Mar 13, 2026

https://screenrec.com/share/xM8Ibk2COs
@e35ventura I updated the demo video. please review it and let me know your feedback.

MkDev11 added 2 commits March 13, 2026 21:17
… demo fills

- Update option_pricing/BTC.json: strikes 68000-74000 centered on $71,181
- Update exchange mock data with full strike coverage (old 65000-68500 + new 69000-74000)
- Scale prediction_percentiles BTC_24h/BTC_1h to center on new price
- Ensures: live testnet orders fill (near-ATM liquidity), guardrail triggers
  (fusion='unclear'), and all 177 tests pass
- Demo shows real 2-leg bull put credit spread filled on Deribit testnet
Addresses owner feedback: demo should focus on trade execution, not
unchanged analysis screens. Usage: --screen none --execute best
@MkDev11
Copy link
Contributor Author

MkDev11 commented Mar 13, 2026

13.03.2026_13.23.08_REC.mp4

@MkDev11
Copy link
Contributor Author

MkDev11 commented Mar 13, 2026

@e35ventura I just updated the demo video

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Options GPS: Autonomous Execution

2 participants