# OKX Codex Trader Design ## Goal Build a minimal local CLI project that: - fetches OKX perpetual futures market data - backtests a strategy on historical candles - asks local Codex CLI to analyze recent market data and return a trading decision - sends simulated orders to OKX Demo Trading The first version is limited to: - `BTC-USDT-SWAP` - `ETH-USDT-SWAP` - isolated margin only - leverage range `1x` to `3x` - OKX demo trading only ## Non-Goals This version does not include: - spot trading - cross margin - live trading - multi-exchange support - portfolio management across symbols - order book level backtesting - automatic daemonized trading loops - web UI ## Project Shape The project will live at `/home/lxy/okx-codex-trader`. The codebase will contain these modules: - `okx_codex_trader/cli.py` - command entrypoint - `okx_codex_trader/config.py` - loads required environment variables - `okx_codex_trader/models.py` - dataclasses for candles, signals, orders, positions, and backtest results - `okx_codex_trader/okx_client.py` - OKX REST client for market data, account reads, leverage setup, and demo orders - `okx_codex_trader/backtest.py` - local candle-based backtest engine - `okx_codex_trader/strategy.py` - deterministic backtest strategy and signal validation rules - `okx_codex_trader/codex_analyzer.py` - invokes local `codex` command and parses the returned JSON signal ## Commands The first version exposes exactly these commands: - `fetch-history` - fetch candles for a symbol and timeframe - required arguments: - `--symbol` with value `BTC-USDT-SWAP` or `ETH-USDT-SWAP` - `--bar` for OKX candle timeframe - `--limit` for candle count - output: - JSON array of normalized candles to stdout - `backtest` - run a local candle-based backtest with the built-in dual moving average strategy - required arguments: - `--symbol` with value `BTC-USDT-SWAP` or `ETH-USDT-SWAP` - `--bar` for OKX candle timeframe - `--limit` for candle count - `--leverage` in `1..3` - output: - one JSON object with summary metrics and per-trade results - `analyze` - send recent candles to Codex CLI and return a structured decision - required arguments: - `--symbol` with value `BTC-USDT-SWAP` or `ETH-USDT-SWAP` - `--bar` for OKX candle timeframe - `--limit` for candle count - `--output-file` for the validated signal JSON - output: - validated signal JSON written to the target file - the same signal JSON printed to stdout - `paper-order` - read a structured signal from `--signal-file` and place a demo order on OKX - required arguments: - `--symbol` with value `BTC-USDT-SWAP` or `ETH-USDT-SWAP` - `--signal-file ` - `--margin-usdt ` - output: - one JSON object describing the no-op result or submitted OKX order - `positions` - show current demo positions - required arguments: - `--symbol` with value `BTC-USDT-SWAP` or `ETH-USDT-SWAP` - output: - JSON array of normalized current positions ## Data Flow ### Historical Backtest The v1 backtest strategy is fixed: - indicator family: simple moving averages - fast window: `10` - slow window: `20` - signal source: candle close - long entry: fast SMA crosses above slow SMA - short entry: fast SMA crosses below slow SMA - entry price: next candle open after a crossover signal - exit price: next candle open after the opposite crossover signal - position sizing: use `100%` of current backtest equity as isolated margin for each trade - leverage: CLI input, limited to integer `1..3` - fees: `0` - slippage: `0` - take profit / stop loss in backtest: not used in v1 - initial equity: `10,000 USDT` - if a position remains open at the end of the candle range: - do not create a synthetic closing trade - keep `trade_count` and `trades` limited to realized exits only - compute summary `ending_equity` and `total_return` from final-candle-close mark-to-market equity - compute `max_drawdown` using the same mark-to-market equity path There are no separate configurable risk parameters in v1. The backtest input is fully defined by: - symbol - timeframe - candle range - leverage 1. CLI requests historical candles from OKX. 2. The OKX client returns normalized candle objects. 3. The backtest engine iterates through candles in time order. 4. The strategy input is reduced to: - symbol - timeframe - recent candles - leverage - candle range 5. The engine simulates entry and exit using candle OHLC values. 6. The result reports: - total return - win rate - max drawdown - trade count - per-trade summary ### Codex Analysis 1. CLI fetches recent candles. 2. The analyzer builds a strict prompt telling Codex to return JSON only. 3. Codex returns a structured trading decision. 4. The analyzer validates that response before any order path can use it. The allowed signal shape is: - `action`: `long`, `short`, or `flat` - `confidence`: `0` to `1` - `leverage`: integer `1` to `3` - `entry_price`: number or `null` - `take_profit_price`: number or `null` - `stop_loss_price`: number or `null` - `reason`: short string If the JSON is invalid, the command fails. No fallback logic is added. ### Demo Order Path The order translation contract is fixed in v1: - `paper-order` input - requires `--signal-file ` - reads one JSON signal object from that file - requires `--margin-usdt ` - `action = flat` - `paper-order` does not send any OKX order - the command returns a no-op result - `entry_price = null` - submit a market order - `entry_price = number` - submit a limit order at that price - `take_profit_price` - accepted in validated signal output - not submitted to OKX in v1 - `stop_loss_price` - accepted in validated signal output - not submitted to OKX in v1 The v1 `paper-order` command places only the primary entry order. It does not create linked TP/SL algo orders. The v1 sizing rule is fixed: - `margin_usdt` is provided explicitly by the user - order notional is `margin_usdt * leverage` - price basis is: - `entry_price` when a limit order is requested - latest market price when a market order is requested - the client must fetch OKX instrument metadata for the symbol before sizing - the client uses `ctVal`, `lotSz`, and `minSz` from the OKX instrument response - for linear swaps, contract count is computed from order notional and price basis using contract value - contract count is rounded down to the nearest valid multiple of `lotSz` - if the rounded contract count is smaller than `minSz`, the command fails The OKX mapping is fixed to hedge mode semantics: - `action = long` - `side = buy` - `posSide = long` - `action = short` - `side = sell` - `posSide = short` - `tdMode = isolated` - position mode must be hedge mode for v1 short and long symmetry - the client checks current position mode before order submission - if the account is not already in hedge mode, the command fails 1. CLI receives a validated order request. 2. The OKX client sets isolated leverage for the symbol and side. 3. The OKX client submits an OKX demo order. 4. The response is returned as normalized order output. ### Runtime Contract The project requires these environment variables: - `OKX_API_KEY` - `OKX_API_SECRET` - `OKX_API_PASSPHRASE` The project also requires a local `codex` executable to be available on `PATH`. There is no required environment variable for Codex in v1. ## Constraints - All authenticated OKX requests must use demo trading mode. - All order requests must target swap instruments only. - All leverage values outside `1..3` are rejected immediately. - Margin mode is fixed to isolated. - Backtest strategy is fixed to the built-in `10/20` SMA crossover. - Position mode is required to already be hedge mode. - The project accepts user input and OKX API responses as system boundaries. Validation is limited to those boundaries. ## Error Handling Only boundary failures are handled: - missing environment variables - missing `codex` executable on `PATH` - invalid user CLI arguments - invalid Codex JSON output - OKX HTTP or API errors - account position mode not set to hedge mode - computed contract size below OKX minimum size There is no internal fallback branch for malformed intermediate state. Failures stop the command directly. ## Testing The implementation will follow test-first for the minimal behaviors: - config loading fails when required keys are missing - analyzer fails when `codex` is not on `PATH` - Codex analyzer rejects non-JSON or out-of-range leverage - backtest computes expected results for the fixed `10/20` SMA crossover on a known candle series - OKX request signing and demo headers are attached correctly - `paper-order` maps `entry_price = null` to market and `entry_price = number` to limit - `paper-order` returns no-op for `action = flat` - `paper-order` reads the signal from `--signal-file` - `paper-order` sizes the order from explicit `margin_usdt` - `paper-order` maps `long` and `short` to the fixed OKX `side` and `posSide` fields - `paper-order` fails when account mode is not hedge mode - contract sizing rounds down by `lotSz` and fails below `minSz` - CLI command parsing dispatches the expected workflow External OKX calls will not be required in unit tests. HTTP interactions will be mocked at the client boundary. ## Implementation Order 1. Create project skeleton and Python package metadata. 2. Add tests for config loading and signal validation. 3. Implement config and models. 4. Add tests for backtest behavior. 5. Implement candle-based backtest engine. 6. Add tests for OKX request construction. 7. Implement OKX client. 8. Add tests for Codex analyzer parsing. 9. Implement Codex analyzer. 10. Add CLI tests. 11. Implement CLI commands. ## Success Criteria The first version is complete when: - `fetch-history` prints normalized historical candles from OKX - `backtest` runs locally on OKX candle data - `analyze` returns validated JSON from local Codex CLI - `paper-order` sends an OKX demo swap order in isolated mode with leverage `1..3` - `positions` returns current demo positions