# Architecture The project has three layers: 1. `okx_codex_trader/`: reusable trading, data, reporting, and research primitives. 2. `scripts/`: experiment entrypoints and live runners. A script can define a strategy variant and grid, but should import shared candle loading, time rules, and metrics from the package. 3. `reports/`: generated outputs only. ## Reusable Modules - `okx_codex_trader/candles.py` - Loads OKX candle CSV files into `Candle`. - Aligns candle streams by timestamp for cross-symbol strategies. - `okx_codex_trader/time_rules.py` - Owns UTC, New York, and Beijing session rules. - Provides entry filters and session buckets used by time-cycle strategies. - US session names are clock windows, not an exchange holiday calendar. - `okx_codex_trader/research_metrics.py` - Owns common research accounting constants. - Builds cost-adjusted equity curves. - Computes total return, annualized return, drawdown, Calmar, horizon rows, trade stats, and worst month. ## Current Boundary Strategy mechanics still live in individual scripts because the search space is changing quickly. The first extracted script is `scripts/search_eth_time_cycle_filters.py`; future strategy searches should follow that shape: 1. Define only the strategy variant and signal logic in the script. 2. Load candles through `load_candles_csv`. 3. Use `time_rules` for all session filters. 4. Use `research_metrics` for all net-return, horizon, and trade-summary statistics. This keeps experiments easy to compose without forcing a generic strategy framework before the live strategy stabilizes. Currently migrated strategy searches: - `scripts/search_eth_time_cycle_filters.py` - `scripts/search_eth_bb_squeeze_fixed_rr.py` - `scripts/search_eth_bb_squeeze_profit_protection.py` `scripts/search_eth_dynamic_atr_exits.py` still keeps local metrics because it reports `full` horizon and horizon-level trade stats from `exit_ts`; extracting that needs a separate direct change to `research_metrics`. ## Multi-Timeframe Execution Research The current live BB squeeze strategy uses 15m candles for both signals and research execution. That is intentionally simple, but it makes entry and exit sequencing coarse: a 15m candle only gives open, high, low, and close, not the local path. The next research step is a two-layer model: 1. Keep 15m candles for the primary strategy signal. 2. Use local 3m candles inside each 15m decision window to model execution and exits. The first scope is exit-only refinement: - 15m still decides whether a position should exist. - 3m checks stop-loss, take-profit, and breakeven activation/exit ordering while the 15m position is open. - 15m middle-exit remains a next-open signal exit unless a 3m risk exit happens first. Entry refinement is a later step. It should only be tested after the exit-only version is measured, because changing entry and exit together makes attribution unclear. Current 3m entry research tested three local execution families: - 3m momentum confirmation: wait for the first 3m candle in the execution window to close in the signal direction, then enter on the next 3m open. - 3m pullback entry: wait for a 0.05%-0.3% local pullback, then enter on the next 3m open. - 3m TWAP entry: use the average of the first 2-5 3m opens as the entry price. The first result is not enough to replace the live execution rule: - 3m risk-only improves full-period results against the 15m baseline without changing recent windows. - Pullback entry, especially 0.1%-0.2%, improves recent 1y/6m/3m windows, but weakens full-period robustness. - TWAP entry improves some recent windows but materially weakens full-period performance. The next direct research path is a regime-gated 3m entry selector: use 15m baseline or 3m risk-only as the default, and only enable pullback entry in regimes where the recent market structure supports it.