From a55283d7d93c1a563fdbd52ff3a116555f07010e Mon Sep 17 00:00:00 2001
From: JaeLeex
Date: Thu, 2 Jul 2026 16:04:13 -0400
Subject: [PATCH 1/2] chore: archive APEX stack and remove SEDA from hedge path
Move APEX/Radar/Pulse/Guard/Reflect, quoting_engine, adapters, deploy
templates, and related tests to _archive/. Hedge K2 inputs now come from
Hyperliquid funding history via strategies/cfi_funding.py with no SEDA oracle.
Co-authored-by: Cursor
---
README.md | 10 +-
_archive/README.md | 34 ++++
{adapters => _archive/adapters}/__init__.py | 0
{adapters => _archive/adapters}/hl_adapter.py | 0
.../adapters}/mock_adapter.py | 0
{cli => _archive/cli}/commands/apex.py | 0
{cli => _archive/cli}/commands/guard.py | 0
{cli => _archive/cli}/commands/pulse.py | 0
{cli => _archive/cli}/commands/radar.py | 0
{cli => _archive/cli}/commands/reflect.py | 0
{configs => _archive/configs}/yex_btcswp.yaml | 0
.../configs}/yex_us3m_protected.yaml | 0
.../configs}/yex_vxx_protected.yaml | 0
.../deploy}/hermes-railway/Dockerfile | 0
.../deploy}/hermes-railway/package.json | 0
.../deploy}/hermes-railway/railway.toml | 4 +-
.../deploy}/hermes-railway/src/bootstrap.mjs | 0
.../deploy}/hermes-railway/src/gateway.js | 0
.../deploy}/hermes-railway/src/onboard.js | 0
.../deploy}/hermes-railway/src/server.js | 0
.../deploy}/hermes-railway/src/status.js | 0
.../hermes-railway/workspace/AGENTS.md | 0
.../hermes-railway/workspace/BOOTSTRAP.md | 0
.../deploy}/hermes-railway/workspace/SOUL.md | 0
.../deploy}/hermes-railway/workspace/TOOLS.md | 0
.../deploy}/openclaw-railway/.env.example | 0
.../deploy}/openclaw-railway/Dockerfile | 0
.../deploy}/openclaw-railway/package.json | 0
.../deploy}/openclaw-railway/railway.toml | 4 +-
.../openclaw-railway/src/bootstrap.mjs | 0
.../deploy}/openclaw-railway/src/gateway.js | 0
.../deploy}/openclaw-railway/src/onboard.js | 0
.../deploy}/openclaw-railway/src/server.js | 0
.../deploy}/openclaw-railway/src/status.js | 0
.../openclaw-railway/workspace/AGENTS.md | 0
.../openclaw-railway/workspace/BOOTSTRAP.md | 0
.../openclaw-railway/workspace/SOUL.md | 0
.../openclaw-railway/workspace/TOOLS.md | 0
{docs => _archive/docs}/hl_feature_audit.md | 2 +-
.../execution}/portfolio_risk.py | 0
{modules => _archive/modules}/apex_config.py | 0
{modules => _archive/modules}/apex_engine.py | 0
{modules => _archive/modules}/apex_state.py | 0
{modules => _archive/modules}/guard_bridge.py | 0
{modules => _archive/modules}/guard_config.py | 0
{modules => _archive/modules}/guard_state.py | 0
{modules => _archive/modules}/pulse_config.py | 0
{modules => _archive/modules}/pulse_engine.py | 0
{modules => _archive/modules}/pulse_guard.py | 0
{modules => _archive/modules}/pulse_state.py | 0
{modules => _archive/modules}/radar_config.py | 0
{modules => _archive/modules}/radar_engine.py | 0
{modules => _archive/modules}/radar_guard.py | 0
{modules => _archive/modules}/radar_state.py | 0
.../modules}/radar_technicals.py | 0
.../modules}/reflect_adapter.py | 0
.../modules}/reflect_convergence.py | 0
.../modules}/reflect_reporter.py | 0
.../quoting_engine}/__init__.py | 0
.../quoting_engine}/config.py | 0
.../configs/events/default_calendar.yaml | 0
.../quoting_engine}/configs/funding_rate.yaml | 0
.../quoting_engine}/configs/us3m.yaml | 0
.../quoting_engine}/configs/vxxn.yaml | 0
.../quoting_engine}/engine.py | 0
.../quoting_engine}/event_schedule.py | 0
.../quoting_engine}/fair_value.py | 0
.../quoting_engine}/feeds/__init__.py | 0
.../quoting_engine}/feeds/base.py | 0
.../quoting_engine}/feeds/funding_rate.py | 0
.../quoting_engine}/feeds/microprice.py | 0
.../quoting_engine}/feeds/oracle_monitor.py | 0
.../quoting_engine}/feeds/seda_oracle.py | 0
.../quoting_engine}/inventory.py | 0
.../quoting_engine}/ladder.py | 0
.../quoting_engine}/metrics.py | 0
.../quoting_engine}/spread.py | 0
.../quoting_engine}/toxicity.py | 0
.../quoting_engine}/vol_estimator.py | 0
.../scripts}/backtest_apex.py | 0
.../scripts}/run_protected_mm.sh | 0
{skills => _archive/skills}/apex/SKILL.md | 0
.../skills}/apex/scripts/standalone_runner.py | 0
{skills => _archive/skills}/guard/SKILL.md | 0
.../guard/scripts/standalone_runner.py | 0
{skills => _archive/skills}/pulse/SKILL.md | 0
.../pulse/scripts/standalone_runner.py | 0
{skills => _archive/skills}/radar/SKILL.md | 0
.../radar/scripts/standalone_runner.py | 0
{skills => _archive/skills}/reflect/SKILL.md | 0
{tasks => _archive/tasks}/todo.md | 0
{tests => _archive/tests}/test_alo_routing.py | 0
{tests => _archive/tests}/test_apex_engine.py | 0
.../tests}/test_apex_reflect_ops.py | 0
.../tests}/test_backtest_harness.py | 0
{tests => _archive/tests}/test_exchange_sl.py | 0
.../tests}/test_guard_bridge.py | 0
.../tests}/test_guard_implementations.py | 0
.../tests}/test_guard_state_full.py | 0
.../tests}/test_integration_phase3.py | 0
.../tests}/test_integration_phase4.py | 0
.../tests}/test_integration_safety.py | 0
.../tests}/test_market_strategy_routing.py | 0
.../tests}/test_memory_engine.py | 0
.../tests}/test_multi_wallet.py | 0
.../tests}/test_portfolio_risk.py | 0
.../tests}/test_pulse_engine.py | 0
.../tests}/test_radar_engine.py | 0
.../tests}/test_radar_technicals.py | 0
.../tests}/test_reflect_adapter_full.py | 0
.../tests}/test_reflect_convergence.py | 0
.../tests}/test_reflect_engine.py | 0
.../tests}/test_reflect_reporter.py | 0
.../tests}/test_signal_taxonomy.py | 0
{tests => _archive/tests}/test_smart_money.py | 0
.../tests}/test_status_reader.py | 0
.../tests}/test_trailing_stop.py | 0
.../tests}/test_venue_adapter.py | 0
cli/api/status_reader.py | 2 +-
cli/commands/hedge.py | 16 +-
cli/commands/run.py | 16 --
cli/engine.py | 120 +-------------
cli/hedge_display.py | 2 +-
cli/main.py | 10 --
cli/mcp_server.py | 84 +---------
pyproject.toml | 4 +-
scripts/entrypoint.py | 84 +---------
scripts/validate_agent_cli.py | 97 +-----------
strategies/cfi_funding.py | 146 ++++++++++++++++++
strategies/cfi_hedge.py | 2 +-
tests/_archive/README.md | 11 +-
.../{ => _archive}/quoting_engine/conftest.py | 9 ++
.../quoting_engine/test_qe_config.py | 0
.../quoting_engine/test_qe_disagreement.py | 0
.../quoting_engine/test_qe_engine.py | 0
.../test_qe_event_schedule_calendar.py | 0
.../quoting_engine/test_qe_fair_value.py | 0
.../quoting_engine/test_qe_feeds_base.py | 0
.../test_qe_funding_boundary.py | 0
.../test_qe_funding_rate_feed.py | 0
.../quoting_engine/test_qe_fv_band.py | 0
.../quoting_engine/test_qe_inventory.py | 0
.../quoting_engine/test_qe_inventory_caps.py | 0
.../quoting_engine/test_qe_ladder.py | 0
.../quoting_engine/test_qe_liq_advanced.py | 0
.../quoting_engine/test_qe_metrics.py | 0
.../quoting_engine/test_qe_microprice.py | 0
.../quoting_engine/test_qe_oracle_monitor.py | 0
.../quoting_engine/test_qe_regime.py | 0
.../quoting_engine/test_qe_spread.py | 0
.../quoting_engine/test_qe_toxicity.py | 0
.../quoting_engine/test_qe_toxicity_tiered.py | 0
.../quoting_engine/test_qe_vol_estimator.py | 0
tests/test_builder_fee.py | 20 ---
tests/test_entrypoint.py | 50 +-----
tests/test_mcp_annotations.py | 1 -
156 files changed, 248 insertions(+), 480 deletions(-)
create mode 100644 _archive/README.md
rename {adapters => _archive/adapters}/__init__.py (100%)
rename {adapters => _archive/adapters}/hl_adapter.py (100%)
rename {adapters => _archive/adapters}/mock_adapter.py (100%)
rename {cli => _archive/cli}/commands/apex.py (100%)
rename {cli => _archive/cli}/commands/guard.py (100%)
rename {cli => _archive/cli}/commands/pulse.py (100%)
rename {cli => _archive/cli}/commands/radar.py (100%)
rename {cli => _archive/cli}/commands/reflect.py (100%)
rename {configs => _archive/configs}/yex_btcswp.yaml (100%)
rename {configs => _archive/configs}/yex_us3m_protected.yaml (100%)
rename {configs => _archive/configs}/yex_vxx_protected.yaml (100%)
rename {deploy => _archive/deploy}/hermes-railway/Dockerfile (100%)
rename {deploy => _archive/deploy}/hermes-railway/package.json (100%)
rename {deploy => _archive/deploy}/hermes-railway/railway.toml (78%)
rename {deploy => _archive/deploy}/hermes-railway/src/bootstrap.mjs (100%)
rename {deploy => _archive/deploy}/hermes-railway/src/gateway.js (100%)
rename {deploy => _archive/deploy}/hermes-railway/src/onboard.js (100%)
rename {deploy => _archive/deploy}/hermes-railway/src/server.js (100%)
rename {deploy => _archive/deploy}/hermes-railway/src/status.js (100%)
rename {deploy => _archive/deploy}/hermes-railway/workspace/AGENTS.md (100%)
rename {deploy => _archive/deploy}/hermes-railway/workspace/BOOTSTRAP.md (100%)
rename {deploy => _archive/deploy}/hermes-railway/workspace/SOUL.md (100%)
rename {deploy => _archive/deploy}/hermes-railway/workspace/TOOLS.md (100%)
rename {deploy => _archive/deploy}/openclaw-railway/.env.example (100%)
rename {deploy => _archive/deploy}/openclaw-railway/Dockerfile (100%)
rename {deploy => _archive/deploy}/openclaw-railway/package.json (100%)
rename {deploy => _archive/deploy}/openclaw-railway/railway.toml (79%)
rename {deploy => _archive/deploy}/openclaw-railway/src/bootstrap.mjs (100%)
rename {deploy => _archive/deploy}/openclaw-railway/src/gateway.js (100%)
rename {deploy => _archive/deploy}/openclaw-railway/src/onboard.js (100%)
rename {deploy => _archive/deploy}/openclaw-railway/src/server.js (100%)
rename {deploy => _archive/deploy}/openclaw-railway/src/status.js (100%)
rename {deploy => _archive/deploy}/openclaw-railway/workspace/AGENTS.md (100%)
rename {deploy => _archive/deploy}/openclaw-railway/workspace/BOOTSTRAP.md (100%)
rename {deploy => _archive/deploy}/openclaw-railway/workspace/SOUL.md (100%)
rename {deploy => _archive/deploy}/openclaw-railway/workspace/TOOLS.md (100%)
rename {docs => _archive/docs}/hl_feature_audit.md (98%)
rename {execution => _archive/execution}/portfolio_risk.py (100%)
rename {modules => _archive/modules}/apex_config.py (100%)
rename {modules => _archive/modules}/apex_engine.py (100%)
rename {modules => _archive/modules}/apex_state.py (100%)
rename {modules => _archive/modules}/guard_bridge.py (100%)
rename {modules => _archive/modules}/guard_config.py (100%)
rename {modules => _archive/modules}/guard_state.py (100%)
rename {modules => _archive/modules}/pulse_config.py (100%)
rename {modules => _archive/modules}/pulse_engine.py (100%)
rename {modules => _archive/modules}/pulse_guard.py (100%)
rename {modules => _archive/modules}/pulse_state.py (100%)
rename {modules => _archive/modules}/radar_config.py (100%)
rename {modules => _archive/modules}/radar_engine.py (100%)
rename {modules => _archive/modules}/radar_guard.py (100%)
rename {modules => _archive/modules}/radar_state.py (100%)
rename {modules => _archive/modules}/radar_technicals.py (100%)
rename {modules => _archive/modules}/reflect_adapter.py (100%)
rename {modules => _archive/modules}/reflect_convergence.py (100%)
rename {modules => _archive/modules}/reflect_reporter.py (100%)
rename {quoting_engine => _archive/quoting_engine}/__init__.py (100%)
rename {quoting_engine => _archive/quoting_engine}/config.py (100%)
rename {quoting_engine => _archive/quoting_engine}/configs/events/default_calendar.yaml (100%)
rename {quoting_engine => _archive/quoting_engine}/configs/funding_rate.yaml (100%)
rename {quoting_engine => _archive/quoting_engine}/configs/us3m.yaml (100%)
rename {quoting_engine => _archive/quoting_engine}/configs/vxxn.yaml (100%)
rename {quoting_engine => _archive/quoting_engine}/engine.py (100%)
rename {quoting_engine => _archive/quoting_engine}/event_schedule.py (100%)
rename {quoting_engine => _archive/quoting_engine}/fair_value.py (100%)
rename {quoting_engine => _archive/quoting_engine}/feeds/__init__.py (100%)
rename {quoting_engine => _archive/quoting_engine}/feeds/base.py (100%)
rename {quoting_engine => _archive/quoting_engine}/feeds/funding_rate.py (100%)
rename {quoting_engine => _archive/quoting_engine}/feeds/microprice.py (100%)
rename {quoting_engine => _archive/quoting_engine}/feeds/oracle_monitor.py (100%)
rename {quoting_engine => _archive/quoting_engine}/feeds/seda_oracle.py (100%)
rename {quoting_engine => _archive/quoting_engine}/inventory.py (100%)
rename {quoting_engine => _archive/quoting_engine}/ladder.py (100%)
rename {quoting_engine => _archive/quoting_engine}/metrics.py (100%)
rename {quoting_engine => _archive/quoting_engine}/spread.py (100%)
rename {quoting_engine => _archive/quoting_engine}/toxicity.py (100%)
rename {quoting_engine => _archive/quoting_engine}/vol_estimator.py (100%)
rename {scripts => _archive/scripts}/backtest_apex.py (100%)
rename {scripts => _archive/scripts}/run_protected_mm.sh (100%)
rename {skills => _archive/skills}/apex/SKILL.md (100%)
rename {skills => _archive/skills}/apex/scripts/standalone_runner.py (100%)
rename {skills => _archive/skills}/guard/SKILL.md (100%)
rename {skills => _archive/skills}/guard/scripts/standalone_runner.py (100%)
rename {skills => _archive/skills}/pulse/SKILL.md (100%)
rename {skills => _archive/skills}/pulse/scripts/standalone_runner.py (100%)
rename {skills => _archive/skills}/radar/SKILL.md (100%)
rename {skills => _archive/skills}/radar/scripts/standalone_runner.py (100%)
rename {skills => _archive/skills}/reflect/SKILL.md (100%)
rename {tasks => _archive/tasks}/todo.md (100%)
rename {tests => _archive/tests}/test_alo_routing.py (100%)
rename {tests => _archive/tests}/test_apex_engine.py (100%)
rename {tests => _archive/tests}/test_apex_reflect_ops.py (100%)
rename {tests => _archive/tests}/test_backtest_harness.py (100%)
rename {tests => _archive/tests}/test_exchange_sl.py (100%)
rename {tests => _archive/tests}/test_guard_bridge.py (100%)
rename {tests => _archive/tests}/test_guard_implementations.py (100%)
rename {tests => _archive/tests}/test_guard_state_full.py (100%)
rename {tests => _archive/tests}/test_integration_phase3.py (100%)
rename {tests => _archive/tests}/test_integration_phase4.py (100%)
rename {tests => _archive/tests}/test_integration_safety.py (100%)
rename {tests => _archive/tests}/test_market_strategy_routing.py (100%)
rename {tests => _archive/tests}/test_memory_engine.py (100%)
rename {tests => _archive/tests}/test_multi_wallet.py (100%)
rename {tests => _archive/tests}/test_portfolio_risk.py (100%)
rename {tests => _archive/tests}/test_pulse_engine.py (100%)
rename {tests => _archive/tests}/test_radar_engine.py (100%)
rename {tests => _archive/tests}/test_radar_technicals.py (100%)
rename {tests => _archive/tests}/test_reflect_adapter_full.py (100%)
rename {tests => _archive/tests}/test_reflect_convergence.py (100%)
rename {tests => _archive/tests}/test_reflect_engine.py (100%)
rename {tests => _archive/tests}/test_reflect_reporter.py (100%)
rename {tests => _archive/tests}/test_signal_taxonomy.py (100%)
rename {tests => _archive/tests}/test_smart_money.py (100%)
rename {tests => _archive/tests}/test_status_reader.py (100%)
rename {tests => _archive/tests}/test_trailing_stop.py (100%)
rename {tests => _archive/tests}/test_venue_adapter.py (100%)
create mode 100644 strategies/cfi_funding.py
rename tests/{ => _archive}/quoting_engine/conftest.py (78%)
rename tests/{ => _archive}/quoting_engine/test_qe_config.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_disagreement.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_engine.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_event_schedule_calendar.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_fair_value.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_feeds_base.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_funding_boundary.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_funding_rate_feed.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_fv_band.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_inventory.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_inventory_caps.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_ladder.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_liq_advanced.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_metrics.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_microprice.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_oracle_monitor.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_regime.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_spread.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_toxicity.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_toxicity_tiered.py (100%)
rename tests/{ => _archive}/quoting_engine/test_qe_vol_estimator.py (100%)
diff --git a/README.md b/README.md
index 4851768..6834549 100644
--- a/README.md
+++ b/README.md
@@ -32,7 +32,9 @@
---
-Ship CFI v2 funding-rate hedging on [Hyperliquid](https://hyperliquid.xyz) perps and Paragon HIP-3 BTCSWP swap markets (`para:BTCSWP` mainnet, `osrs:BTCSWP` / `yex:BTCSWP` testnet). Primary surface: `hl hedge propose|execute|status|auto|backtest`. Also exposes Guard, Radar, Pulse, APEX, and REFLECT as optional operator tools. Works as a standalone CLI, a [Claude Code](https://docs.anthropic.com/en/docs/claude-code) skill, an [OpenClaw](https://agentskills.io) or [Hermes](https://github.com/NousResearch/hermes-agent) agent toolset, or a standalone MCP server.
+Ship CFI v2 funding-rate hedging on [Hyperliquid](https://hyperliquid.xyz) perps and Paragon HIP-3 BTCSWP swap markets (`para:BTCSWP` mainnet, `osrs:BTCSWP` / `yex:BTCSWP` testnet). Primary surface: `hl hedge propose|execute|status|auto|backtest`. K2 inputs come from HL funding history only (no SEDA). Works as a standalone CLI, a [Claude Code](https://docs.anthropic.com/en/docs/claude-code) skill, or a standalone MCP server.
+
+Legacy operator stack (APEX, Radar, Pulse, Guard, Reflect, quoting engine, SEDA oracle, Hermes/OpenClaw deploy) was archived 2026-07-02 under `_archive/` — see `_archive/README.md`.
---
@@ -524,7 +526,7 @@ mcp_servers:
# cwd: /path/to/agent-cli # if not launched from the repo root
```
-This is exactly what `deploy/hermes-railway` auto-generates on boot (alongside `platform_toolsets`), so a deployed Hermes agent is wired out of the box — no OpenClaw-specific assumptions anywhere in the MCP server.
+This is exactly what the legacy `archive/deploy/hermes-railway` template auto-generates on boot (alongside `platform_toolsets`), so a deployed Hermes agent is wired out of the box — no OpenClaw-specific assumptions anywhere in the MCP server.
### HTTP API & SSE
@@ -565,8 +567,8 @@ self-host templates. They are not part of the new hosted MCP subscription
architecture because they provision user-facing conversational/autonomous
agents. Do not expose them as the paid Nunchi product path.
-For legacy experiments, use `deploy/openclaw-railway/railway.toml` or
-`deploy/hermes-railway/railway.toml` as the config-as-code path and keep the
+For legacy experiments, use `archive/deploy/openclaw-railway/railway.toml` or
+`archive/deploy/hermes-railway/railway.toml` as the config-as-code path and keep the
Railway build root at the repo root.
---
diff --git a/_archive/README.md b/_archive/README.md
new file mode 100644
index 0000000..0d4d75e
--- /dev/null
+++ b/_archive/README.md
@@ -0,0 +1,34 @@
+# Archived legacy components
+
+**Date:** 2026-07-02
+**Reason:** Product focus narrowed to CFI v2 funding-rate hedge only (`hl hedge`, `cfi_hedge` strategy). The multi-slot APEX orchestrator, Radar/Pulse scanners, Guard trailing stops, Reflect reviews, market-making stack, SEDA oracle, and Hermes/OpenClaw Railway deploy templates are no longer maintained in the active tree.
+
+## What moved here
+
+| Path | Description |
+|------|-------------|
+| `_archive/cli/commands/` | APEX, Radar, Pulse, Guard, Reflect CLI commands |
+| `_archive/modules/` | APEX/Radar/Pulse/Guard/Reflect engines and state |
+| `_archive/skills/` | Agent skills for the legacy operator stack |
+| `_archive/adapters/` | Venue adapter layer for APEX standalone runner |
+| `_archive/quoting_engine/` | Full MM stack; includes `feeds/seda_oracle.py` (deprecated) |
+| `_archive/deploy/` | Hermes + OpenClaw Railway agent gateway templates |
+| `_archive/configs/` | YEX protected-MM configs (US3M, VXX, BTCSWP) |
+| `_archive/execution/portfolio_risk.py` | Portfolio-level entry caps for APEX multi-slot mode |
+| `_archive/scripts/` | `backtest_apex.py`, `run_protected_mm.sh` |
+| `_archive/tests/` | Tests for archived modules and CLI |
+| `_archive/docs/hl_feature_audit.md` | Legacy feature audit notes |
+| `_archive/tasks/todo.md` | Stale task list |
+
+## Active replacement
+
+- **Primary product:** `hl hedge propose|execute|status|auto|backtest` and `hl run cfi_hedge`
+- **K2 inputs:** Hyperliquid funding history via `strategies/cfi_funding.py` (no SEDA oracle)
+- **MCP:** `funding_hedge_propose`, `funding_hedge_execute`, `funding_hedge_backtest`
+
+## Running archived tests manually
+
+```bash
+PYTHONPATH=_archive:. pytest tests/_archive/quoting_engine/ -v
+PYTHONPATH=. pytest _archive/tests/ -v
+```
diff --git a/adapters/__init__.py b/_archive/adapters/__init__.py
similarity index 100%
rename from adapters/__init__.py
rename to _archive/adapters/__init__.py
diff --git a/adapters/hl_adapter.py b/_archive/adapters/hl_adapter.py
similarity index 100%
rename from adapters/hl_adapter.py
rename to _archive/adapters/hl_adapter.py
diff --git a/adapters/mock_adapter.py b/_archive/adapters/mock_adapter.py
similarity index 100%
rename from adapters/mock_adapter.py
rename to _archive/adapters/mock_adapter.py
diff --git a/cli/commands/apex.py b/_archive/cli/commands/apex.py
similarity index 100%
rename from cli/commands/apex.py
rename to _archive/cli/commands/apex.py
diff --git a/cli/commands/guard.py b/_archive/cli/commands/guard.py
similarity index 100%
rename from cli/commands/guard.py
rename to _archive/cli/commands/guard.py
diff --git a/cli/commands/pulse.py b/_archive/cli/commands/pulse.py
similarity index 100%
rename from cli/commands/pulse.py
rename to _archive/cli/commands/pulse.py
diff --git a/cli/commands/radar.py b/_archive/cli/commands/radar.py
similarity index 100%
rename from cli/commands/radar.py
rename to _archive/cli/commands/radar.py
diff --git a/cli/commands/reflect.py b/_archive/cli/commands/reflect.py
similarity index 100%
rename from cli/commands/reflect.py
rename to _archive/cli/commands/reflect.py
diff --git a/configs/yex_btcswp.yaml b/_archive/configs/yex_btcswp.yaml
similarity index 100%
rename from configs/yex_btcswp.yaml
rename to _archive/configs/yex_btcswp.yaml
diff --git a/configs/yex_us3m_protected.yaml b/_archive/configs/yex_us3m_protected.yaml
similarity index 100%
rename from configs/yex_us3m_protected.yaml
rename to _archive/configs/yex_us3m_protected.yaml
diff --git a/configs/yex_vxx_protected.yaml b/_archive/configs/yex_vxx_protected.yaml
similarity index 100%
rename from configs/yex_vxx_protected.yaml
rename to _archive/configs/yex_vxx_protected.yaml
diff --git a/deploy/hermes-railway/Dockerfile b/_archive/deploy/hermes-railway/Dockerfile
similarity index 100%
rename from deploy/hermes-railway/Dockerfile
rename to _archive/deploy/hermes-railway/Dockerfile
diff --git a/deploy/hermes-railway/package.json b/_archive/deploy/hermes-railway/package.json
similarity index 100%
rename from deploy/hermes-railway/package.json
rename to _archive/deploy/hermes-railway/package.json
diff --git a/deploy/hermes-railway/railway.toml b/_archive/deploy/hermes-railway/railway.toml
similarity index 78%
rename from deploy/hermes-railway/railway.toml
rename to _archive/deploy/hermes-railway/railway.toml
index a1db35e..16afa37 100644
--- a/deploy/hermes-railway/railway.toml
+++ b/_archive/deploy/hermes-railway/railway.toml
@@ -2,8 +2,8 @@
builder = "dockerfile"
# Build context is the repo root so the Dockerfile can COPY the agent-cli source.
# Set this service's Root Directory to the repo root (/) in Railway, not
-# deploy/hermes-railway, otherwise `COPY . .` cannot reach the CLI package.
-dockerfilePath = "deploy/hermes-railway/Dockerfile"
+# archive/deploy/hermes-railway, otherwise `COPY . .` cannot reach the CLI package.
+dockerfilePath = "archive/deploy/hermes-railway/Dockerfile"
[deploy]
healthcheckPath = "/health"
diff --git a/deploy/hermes-railway/src/bootstrap.mjs b/_archive/deploy/hermes-railway/src/bootstrap.mjs
similarity index 100%
rename from deploy/hermes-railway/src/bootstrap.mjs
rename to _archive/deploy/hermes-railway/src/bootstrap.mjs
diff --git a/deploy/hermes-railway/src/gateway.js b/_archive/deploy/hermes-railway/src/gateway.js
similarity index 100%
rename from deploy/hermes-railway/src/gateway.js
rename to _archive/deploy/hermes-railway/src/gateway.js
diff --git a/deploy/hermes-railway/src/onboard.js b/_archive/deploy/hermes-railway/src/onboard.js
similarity index 100%
rename from deploy/hermes-railway/src/onboard.js
rename to _archive/deploy/hermes-railway/src/onboard.js
diff --git a/deploy/hermes-railway/src/server.js b/_archive/deploy/hermes-railway/src/server.js
similarity index 100%
rename from deploy/hermes-railway/src/server.js
rename to _archive/deploy/hermes-railway/src/server.js
diff --git a/deploy/hermes-railway/src/status.js b/_archive/deploy/hermes-railway/src/status.js
similarity index 100%
rename from deploy/hermes-railway/src/status.js
rename to _archive/deploy/hermes-railway/src/status.js
diff --git a/deploy/hermes-railway/workspace/AGENTS.md b/_archive/deploy/hermes-railway/workspace/AGENTS.md
similarity index 100%
rename from deploy/hermes-railway/workspace/AGENTS.md
rename to _archive/deploy/hermes-railway/workspace/AGENTS.md
diff --git a/deploy/hermes-railway/workspace/BOOTSTRAP.md b/_archive/deploy/hermes-railway/workspace/BOOTSTRAP.md
similarity index 100%
rename from deploy/hermes-railway/workspace/BOOTSTRAP.md
rename to _archive/deploy/hermes-railway/workspace/BOOTSTRAP.md
diff --git a/deploy/hermes-railway/workspace/SOUL.md b/_archive/deploy/hermes-railway/workspace/SOUL.md
similarity index 100%
rename from deploy/hermes-railway/workspace/SOUL.md
rename to _archive/deploy/hermes-railway/workspace/SOUL.md
diff --git a/deploy/hermes-railway/workspace/TOOLS.md b/_archive/deploy/hermes-railway/workspace/TOOLS.md
similarity index 100%
rename from deploy/hermes-railway/workspace/TOOLS.md
rename to _archive/deploy/hermes-railway/workspace/TOOLS.md
diff --git a/deploy/openclaw-railway/.env.example b/_archive/deploy/openclaw-railway/.env.example
similarity index 100%
rename from deploy/openclaw-railway/.env.example
rename to _archive/deploy/openclaw-railway/.env.example
diff --git a/deploy/openclaw-railway/Dockerfile b/_archive/deploy/openclaw-railway/Dockerfile
similarity index 100%
rename from deploy/openclaw-railway/Dockerfile
rename to _archive/deploy/openclaw-railway/Dockerfile
diff --git a/deploy/openclaw-railway/package.json b/_archive/deploy/openclaw-railway/package.json
similarity index 100%
rename from deploy/openclaw-railway/package.json
rename to _archive/deploy/openclaw-railway/package.json
diff --git a/deploy/openclaw-railway/railway.toml b/_archive/deploy/openclaw-railway/railway.toml
similarity index 79%
rename from deploy/openclaw-railway/railway.toml
rename to _archive/deploy/openclaw-railway/railway.toml
index bd0e575..50d7479 100644
--- a/deploy/openclaw-railway/railway.toml
+++ b/_archive/deploy/openclaw-railway/railway.toml
@@ -2,8 +2,8 @@
builder = "dockerfile"
# Build context is the repo root so the Dockerfile can COPY the agent-cli source.
# Set this service's Root Directory to the repo root (/) in Railway, not
-# deploy/openclaw-railway, otherwise `COPY . .` cannot reach the CLI package.
-dockerfilePath = "deploy/openclaw-railway/Dockerfile"
+# archive/deploy/openclaw-railway, otherwise `COPY . .` cannot reach the CLI package.
+dockerfilePath = "archive/deploy/openclaw-railway/Dockerfile"
[deploy]
healthcheckPath = "/health"
diff --git a/deploy/openclaw-railway/src/bootstrap.mjs b/_archive/deploy/openclaw-railway/src/bootstrap.mjs
similarity index 100%
rename from deploy/openclaw-railway/src/bootstrap.mjs
rename to _archive/deploy/openclaw-railway/src/bootstrap.mjs
diff --git a/deploy/openclaw-railway/src/gateway.js b/_archive/deploy/openclaw-railway/src/gateway.js
similarity index 100%
rename from deploy/openclaw-railway/src/gateway.js
rename to _archive/deploy/openclaw-railway/src/gateway.js
diff --git a/deploy/openclaw-railway/src/onboard.js b/_archive/deploy/openclaw-railway/src/onboard.js
similarity index 100%
rename from deploy/openclaw-railway/src/onboard.js
rename to _archive/deploy/openclaw-railway/src/onboard.js
diff --git a/deploy/openclaw-railway/src/server.js b/_archive/deploy/openclaw-railway/src/server.js
similarity index 100%
rename from deploy/openclaw-railway/src/server.js
rename to _archive/deploy/openclaw-railway/src/server.js
diff --git a/deploy/openclaw-railway/src/status.js b/_archive/deploy/openclaw-railway/src/status.js
similarity index 100%
rename from deploy/openclaw-railway/src/status.js
rename to _archive/deploy/openclaw-railway/src/status.js
diff --git a/deploy/openclaw-railway/workspace/AGENTS.md b/_archive/deploy/openclaw-railway/workspace/AGENTS.md
similarity index 100%
rename from deploy/openclaw-railway/workspace/AGENTS.md
rename to _archive/deploy/openclaw-railway/workspace/AGENTS.md
diff --git a/deploy/openclaw-railway/workspace/BOOTSTRAP.md b/_archive/deploy/openclaw-railway/workspace/BOOTSTRAP.md
similarity index 100%
rename from deploy/openclaw-railway/workspace/BOOTSTRAP.md
rename to _archive/deploy/openclaw-railway/workspace/BOOTSTRAP.md
diff --git a/deploy/openclaw-railway/workspace/SOUL.md b/_archive/deploy/openclaw-railway/workspace/SOUL.md
similarity index 100%
rename from deploy/openclaw-railway/workspace/SOUL.md
rename to _archive/deploy/openclaw-railway/workspace/SOUL.md
diff --git a/deploy/openclaw-railway/workspace/TOOLS.md b/_archive/deploy/openclaw-railway/workspace/TOOLS.md
similarity index 100%
rename from deploy/openclaw-railway/workspace/TOOLS.md
rename to _archive/deploy/openclaw-railway/workspace/TOOLS.md
diff --git a/docs/hl_feature_audit.md b/_archive/docs/hl_feature_audit.md
similarity index 98%
rename from docs/hl_feature_audit.md
rename to _archive/docs/hl_feature_audit.md
index 44f3bab..f0f1692 100644
--- a/docs/hl_feature_audit.md
+++ b/_archive/docs/hl_feature_audit.md
@@ -172,7 +172,7 @@ These read `snapshot.funding_rate` in their trading logic but don't import any H
**Tightly coupled (quoting engine + HyperliquidFundingRate, 4 strategies):**
`engine_mm`, `funding_arb`, `regime_mm`, `liquidation_mm`
-These directly import `HyperliquidFundingRate` from the quoting engine and require `_engine_base.py` (path hack to `~/Tee-work-/quoting_engine`). Porting requires refactoring the quoting engine's funding rate interface.
+These directly import `HyperliquidFundingRate` from the quoting engine (now under `archive/quoting_engine/`) and require `_engine_base.py` (path hack to `~/Tee-work-/quoting_engine`). Porting requires refactoring the quoting engine's funding rate interface.
### Highest-Priority Abstractions for Multi-Exchange Support
diff --git a/execution/portfolio_risk.py b/_archive/execution/portfolio_risk.py
similarity index 100%
rename from execution/portfolio_risk.py
rename to _archive/execution/portfolio_risk.py
diff --git a/modules/apex_config.py b/_archive/modules/apex_config.py
similarity index 100%
rename from modules/apex_config.py
rename to _archive/modules/apex_config.py
diff --git a/modules/apex_engine.py b/_archive/modules/apex_engine.py
similarity index 100%
rename from modules/apex_engine.py
rename to _archive/modules/apex_engine.py
diff --git a/modules/apex_state.py b/_archive/modules/apex_state.py
similarity index 100%
rename from modules/apex_state.py
rename to _archive/modules/apex_state.py
diff --git a/modules/guard_bridge.py b/_archive/modules/guard_bridge.py
similarity index 100%
rename from modules/guard_bridge.py
rename to _archive/modules/guard_bridge.py
diff --git a/modules/guard_config.py b/_archive/modules/guard_config.py
similarity index 100%
rename from modules/guard_config.py
rename to _archive/modules/guard_config.py
diff --git a/modules/guard_state.py b/_archive/modules/guard_state.py
similarity index 100%
rename from modules/guard_state.py
rename to _archive/modules/guard_state.py
diff --git a/modules/pulse_config.py b/_archive/modules/pulse_config.py
similarity index 100%
rename from modules/pulse_config.py
rename to _archive/modules/pulse_config.py
diff --git a/modules/pulse_engine.py b/_archive/modules/pulse_engine.py
similarity index 100%
rename from modules/pulse_engine.py
rename to _archive/modules/pulse_engine.py
diff --git a/modules/pulse_guard.py b/_archive/modules/pulse_guard.py
similarity index 100%
rename from modules/pulse_guard.py
rename to _archive/modules/pulse_guard.py
diff --git a/modules/pulse_state.py b/_archive/modules/pulse_state.py
similarity index 100%
rename from modules/pulse_state.py
rename to _archive/modules/pulse_state.py
diff --git a/modules/radar_config.py b/_archive/modules/radar_config.py
similarity index 100%
rename from modules/radar_config.py
rename to _archive/modules/radar_config.py
diff --git a/modules/radar_engine.py b/_archive/modules/radar_engine.py
similarity index 100%
rename from modules/radar_engine.py
rename to _archive/modules/radar_engine.py
diff --git a/modules/radar_guard.py b/_archive/modules/radar_guard.py
similarity index 100%
rename from modules/radar_guard.py
rename to _archive/modules/radar_guard.py
diff --git a/modules/radar_state.py b/_archive/modules/radar_state.py
similarity index 100%
rename from modules/radar_state.py
rename to _archive/modules/radar_state.py
diff --git a/modules/radar_technicals.py b/_archive/modules/radar_technicals.py
similarity index 100%
rename from modules/radar_technicals.py
rename to _archive/modules/radar_technicals.py
diff --git a/modules/reflect_adapter.py b/_archive/modules/reflect_adapter.py
similarity index 100%
rename from modules/reflect_adapter.py
rename to _archive/modules/reflect_adapter.py
diff --git a/modules/reflect_convergence.py b/_archive/modules/reflect_convergence.py
similarity index 100%
rename from modules/reflect_convergence.py
rename to _archive/modules/reflect_convergence.py
diff --git a/modules/reflect_reporter.py b/_archive/modules/reflect_reporter.py
similarity index 100%
rename from modules/reflect_reporter.py
rename to _archive/modules/reflect_reporter.py
diff --git a/quoting_engine/__init__.py b/_archive/quoting_engine/__init__.py
similarity index 100%
rename from quoting_engine/__init__.py
rename to _archive/quoting_engine/__init__.py
diff --git a/quoting_engine/config.py b/_archive/quoting_engine/config.py
similarity index 100%
rename from quoting_engine/config.py
rename to _archive/quoting_engine/config.py
diff --git a/quoting_engine/configs/events/default_calendar.yaml b/_archive/quoting_engine/configs/events/default_calendar.yaml
similarity index 100%
rename from quoting_engine/configs/events/default_calendar.yaml
rename to _archive/quoting_engine/configs/events/default_calendar.yaml
diff --git a/quoting_engine/configs/funding_rate.yaml b/_archive/quoting_engine/configs/funding_rate.yaml
similarity index 100%
rename from quoting_engine/configs/funding_rate.yaml
rename to _archive/quoting_engine/configs/funding_rate.yaml
diff --git a/quoting_engine/configs/us3m.yaml b/_archive/quoting_engine/configs/us3m.yaml
similarity index 100%
rename from quoting_engine/configs/us3m.yaml
rename to _archive/quoting_engine/configs/us3m.yaml
diff --git a/quoting_engine/configs/vxxn.yaml b/_archive/quoting_engine/configs/vxxn.yaml
similarity index 100%
rename from quoting_engine/configs/vxxn.yaml
rename to _archive/quoting_engine/configs/vxxn.yaml
diff --git a/quoting_engine/engine.py b/_archive/quoting_engine/engine.py
similarity index 100%
rename from quoting_engine/engine.py
rename to _archive/quoting_engine/engine.py
diff --git a/quoting_engine/event_schedule.py b/_archive/quoting_engine/event_schedule.py
similarity index 100%
rename from quoting_engine/event_schedule.py
rename to _archive/quoting_engine/event_schedule.py
diff --git a/quoting_engine/fair_value.py b/_archive/quoting_engine/fair_value.py
similarity index 100%
rename from quoting_engine/fair_value.py
rename to _archive/quoting_engine/fair_value.py
diff --git a/quoting_engine/feeds/__init__.py b/_archive/quoting_engine/feeds/__init__.py
similarity index 100%
rename from quoting_engine/feeds/__init__.py
rename to _archive/quoting_engine/feeds/__init__.py
diff --git a/quoting_engine/feeds/base.py b/_archive/quoting_engine/feeds/base.py
similarity index 100%
rename from quoting_engine/feeds/base.py
rename to _archive/quoting_engine/feeds/base.py
diff --git a/quoting_engine/feeds/funding_rate.py b/_archive/quoting_engine/feeds/funding_rate.py
similarity index 100%
rename from quoting_engine/feeds/funding_rate.py
rename to _archive/quoting_engine/feeds/funding_rate.py
diff --git a/quoting_engine/feeds/microprice.py b/_archive/quoting_engine/feeds/microprice.py
similarity index 100%
rename from quoting_engine/feeds/microprice.py
rename to _archive/quoting_engine/feeds/microprice.py
diff --git a/quoting_engine/feeds/oracle_monitor.py b/_archive/quoting_engine/feeds/oracle_monitor.py
similarity index 100%
rename from quoting_engine/feeds/oracle_monitor.py
rename to _archive/quoting_engine/feeds/oracle_monitor.py
diff --git a/quoting_engine/feeds/seda_oracle.py b/_archive/quoting_engine/feeds/seda_oracle.py
similarity index 100%
rename from quoting_engine/feeds/seda_oracle.py
rename to _archive/quoting_engine/feeds/seda_oracle.py
diff --git a/quoting_engine/inventory.py b/_archive/quoting_engine/inventory.py
similarity index 100%
rename from quoting_engine/inventory.py
rename to _archive/quoting_engine/inventory.py
diff --git a/quoting_engine/ladder.py b/_archive/quoting_engine/ladder.py
similarity index 100%
rename from quoting_engine/ladder.py
rename to _archive/quoting_engine/ladder.py
diff --git a/quoting_engine/metrics.py b/_archive/quoting_engine/metrics.py
similarity index 100%
rename from quoting_engine/metrics.py
rename to _archive/quoting_engine/metrics.py
diff --git a/quoting_engine/spread.py b/_archive/quoting_engine/spread.py
similarity index 100%
rename from quoting_engine/spread.py
rename to _archive/quoting_engine/spread.py
diff --git a/quoting_engine/toxicity.py b/_archive/quoting_engine/toxicity.py
similarity index 100%
rename from quoting_engine/toxicity.py
rename to _archive/quoting_engine/toxicity.py
diff --git a/quoting_engine/vol_estimator.py b/_archive/quoting_engine/vol_estimator.py
similarity index 100%
rename from quoting_engine/vol_estimator.py
rename to _archive/quoting_engine/vol_estimator.py
diff --git a/scripts/backtest_apex.py b/_archive/scripts/backtest_apex.py
similarity index 100%
rename from scripts/backtest_apex.py
rename to _archive/scripts/backtest_apex.py
diff --git a/scripts/run_protected_mm.sh b/_archive/scripts/run_protected_mm.sh
similarity index 100%
rename from scripts/run_protected_mm.sh
rename to _archive/scripts/run_protected_mm.sh
diff --git a/skills/apex/SKILL.md b/_archive/skills/apex/SKILL.md
similarity index 100%
rename from skills/apex/SKILL.md
rename to _archive/skills/apex/SKILL.md
diff --git a/skills/apex/scripts/standalone_runner.py b/_archive/skills/apex/scripts/standalone_runner.py
similarity index 100%
rename from skills/apex/scripts/standalone_runner.py
rename to _archive/skills/apex/scripts/standalone_runner.py
diff --git a/skills/guard/SKILL.md b/_archive/skills/guard/SKILL.md
similarity index 100%
rename from skills/guard/SKILL.md
rename to _archive/skills/guard/SKILL.md
diff --git a/skills/guard/scripts/standalone_runner.py b/_archive/skills/guard/scripts/standalone_runner.py
similarity index 100%
rename from skills/guard/scripts/standalone_runner.py
rename to _archive/skills/guard/scripts/standalone_runner.py
diff --git a/skills/pulse/SKILL.md b/_archive/skills/pulse/SKILL.md
similarity index 100%
rename from skills/pulse/SKILL.md
rename to _archive/skills/pulse/SKILL.md
diff --git a/skills/pulse/scripts/standalone_runner.py b/_archive/skills/pulse/scripts/standalone_runner.py
similarity index 100%
rename from skills/pulse/scripts/standalone_runner.py
rename to _archive/skills/pulse/scripts/standalone_runner.py
diff --git a/skills/radar/SKILL.md b/_archive/skills/radar/SKILL.md
similarity index 100%
rename from skills/radar/SKILL.md
rename to _archive/skills/radar/SKILL.md
diff --git a/skills/radar/scripts/standalone_runner.py b/_archive/skills/radar/scripts/standalone_runner.py
similarity index 100%
rename from skills/radar/scripts/standalone_runner.py
rename to _archive/skills/radar/scripts/standalone_runner.py
diff --git a/skills/reflect/SKILL.md b/_archive/skills/reflect/SKILL.md
similarity index 100%
rename from skills/reflect/SKILL.md
rename to _archive/skills/reflect/SKILL.md
diff --git a/tasks/todo.md b/_archive/tasks/todo.md
similarity index 100%
rename from tasks/todo.md
rename to _archive/tasks/todo.md
diff --git a/tests/test_alo_routing.py b/_archive/tests/test_alo_routing.py
similarity index 100%
rename from tests/test_alo_routing.py
rename to _archive/tests/test_alo_routing.py
diff --git a/tests/test_apex_engine.py b/_archive/tests/test_apex_engine.py
similarity index 100%
rename from tests/test_apex_engine.py
rename to _archive/tests/test_apex_engine.py
diff --git a/tests/test_apex_reflect_ops.py b/_archive/tests/test_apex_reflect_ops.py
similarity index 100%
rename from tests/test_apex_reflect_ops.py
rename to _archive/tests/test_apex_reflect_ops.py
diff --git a/tests/test_backtest_harness.py b/_archive/tests/test_backtest_harness.py
similarity index 100%
rename from tests/test_backtest_harness.py
rename to _archive/tests/test_backtest_harness.py
diff --git a/tests/test_exchange_sl.py b/_archive/tests/test_exchange_sl.py
similarity index 100%
rename from tests/test_exchange_sl.py
rename to _archive/tests/test_exchange_sl.py
diff --git a/tests/test_guard_bridge.py b/_archive/tests/test_guard_bridge.py
similarity index 100%
rename from tests/test_guard_bridge.py
rename to _archive/tests/test_guard_bridge.py
diff --git a/tests/test_guard_implementations.py b/_archive/tests/test_guard_implementations.py
similarity index 100%
rename from tests/test_guard_implementations.py
rename to _archive/tests/test_guard_implementations.py
diff --git a/tests/test_guard_state_full.py b/_archive/tests/test_guard_state_full.py
similarity index 100%
rename from tests/test_guard_state_full.py
rename to _archive/tests/test_guard_state_full.py
diff --git a/tests/test_integration_phase3.py b/_archive/tests/test_integration_phase3.py
similarity index 100%
rename from tests/test_integration_phase3.py
rename to _archive/tests/test_integration_phase3.py
diff --git a/tests/test_integration_phase4.py b/_archive/tests/test_integration_phase4.py
similarity index 100%
rename from tests/test_integration_phase4.py
rename to _archive/tests/test_integration_phase4.py
diff --git a/tests/test_integration_safety.py b/_archive/tests/test_integration_safety.py
similarity index 100%
rename from tests/test_integration_safety.py
rename to _archive/tests/test_integration_safety.py
diff --git a/tests/test_market_strategy_routing.py b/_archive/tests/test_market_strategy_routing.py
similarity index 100%
rename from tests/test_market_strategy_routing.py
rename to _archive/tests/test_market_strategy_routing.py
diff --git a/tests/test_memory_engine.py b/_archive/tests/test_memory_engine.py
similarity index 100%
rename from tests/test_memory_engine.py
rename to _archive/tests/test_memory_engine.py
diff --git a/tests/test_multi_wallet.py b/_archive/tests/test_multi_wallet.py
similarity index 100%
rename from tests/test_multi_wallet.py
rename to _archive/tests/test_multi_wallet.py
diff --git a/tests/test_portfolio_risk.py b/_archive/tests/test_portfolio_risk.py
similarity index 100%
rename from tests/test_portfolio_risk.py
rename to _archive/tests/test_portfolio_risk.py
diff --git a/tests/test_pulse_engine.py b/_archive/tests/test_pulse_engine.py
similarity index 100%
rename from tests/test_pulse_engine.py
rename to _archive/tests/test_pulse_engine.py
diff --git a/tests/test_radar_engine.py b/_archive/tests/test_radar_engine.py
similarity index 100%
rename from tests/test_radar_engine.py
rename to _archive/tests/test_radar_engine.py
diff --git a/tests/test_radar_technicals.py b/_archive/tests/test_radar_technicals.py
similarity index 100%
rename from tests/test_radar_technicals.py
rename to _archive/tests/test_radar_technicals.py
diff --git a/tests/test_reflect_adapter_full.py b/_archive/tests/test_reflect_adapter_full.py
similarity index 100%
rename from tests/test_reflect_adapter_full.py
rename to _archive/tests/test_reflect_adapter_full.py
diff --git a/tests/test_reflect_convergence.py b/_archive/tests/test_reflect_convergence.py
similarity index 100%
rename from tests/test_reflect_convergence.py
rename to _archive/tests/test_reflect_convergence.py
diff --git a/tests/test_reflect_engine.py b/_archive/tests/test_reflect_engine.py
similarity index 100%
rename from tests/test_reflect_engine.py
rename to _archive/tests/test_reflect_engine.py
diff --git a/tests/test_reflect_reporter.py b/_archive/tests/test_reflect_reporter.py
similarity index 100%
rename from tests/test_reflect_reporter.py
rename to _archive/tests/test_reflect_reporter.py
diff --git a/tests/test_signal_taxonomy.py b/_archive/tests/test_signal_taxonomy.py
similarity index 100%
rename from tests/test_signal_taxonomy.py
rename to _archive/tests/test_signal_taxonomy.py
diff --git a/tests/test_smart_money.py b/_archive/tests/test_smart_money.py
similarity index 100%
rename from tests/test_smart_money.py
rename to _archive/tests/test_smart_money.py
diff --git a/tests/test_status_reader.py b/_archive/tests/test_status_reader.py
similarity index 100%
rename from tests/test_status_reader.py
rename to _archive/tests/test_status_reader.py
diff --git a/tests/test_trailing_stop.py b/_archive/tests/test_trailing_stop.py
similarity index 100%
rename from tests/test_trailing_stop.py
rename to _archive/tests/test_trailing_stop.py
diff --git a/tests/test_venue_adapter.py b/_archive/tests/test_venue_adapter.py
similarity index 100%
rename from tests/test_venue_adapter.py
rename to _archive/tests/test_venue_adapter.py
diff --git a/cli/api/status_reader.py b/cli/api/status_reader.py
index 1cda7ce..fa017dc 100644
--- a/cli/api/status_reader.py
+++ b/cli/api/status_reader.py
@@ -2,7 +2,7 @@
Shared utility used by:
- scripts/entrypoint.py (imported directly)
-- deploy/openclaw-railway/src/server.js (via `python3 -m cli.api.status_reader`)
+- archive/deploy/openclaw-railway/src/server.js (via `python3 -m cli.api.status_reader`)
"""
from __future__ import annotations
diff --git a/cli/commands/hedge.py b/cli/commands/hedge.py
index ffcfa63..9f83dd7 100644
--- a/cli/commands/hedge.py
+++ b/cli/commands/hedge.py
@@ -8,8 +8,8 @@
hl hedge backtest --coin BTC [--days N] wrap hedge_calculator.py
hl hedge auto [--coins ...] [--dry-run] agent-controlled auto-open loop
-All math + oracle access is delegated to `strategies/cfi_hedge.py` and
-`quoting_engine/feeds/seda_oracle.py`. Signing + submission are delegated to
+All math + funding inputs are delegated to `strategies/cfi_hedge.py` and
+`strategies/cfi_funding.py` (HL funding rates only). Signing + submission are delegated to
the Hyperliquid Python SDK via `DirectHLProxy.place_order()` — same code path
as `hl trade`. No custom signing here.
"""
@@ -116,8 +116,8 @@ def _build_proposal(
Returns (proposal, snapshot) or raises typer.Exit if no position open.
"""
from strategies.cfi_hedge import build_cfi_hedge_proposal, get_cfi_profile
- from quoting_engine.feeds.seda_oracle import (
- fetch_btcswp_snapshot,
+ from strategies.cfi_funding import (
+ fetch_cfi_funding_snapshot,
fetch_hl_current_funding_hr,
)
@@ -145,7 +145,7 @@ def _build_proposal(
raise typer.Exit(1)
position = _position_to_summary(raw_pos, coin_override=coin)
- snapshot = fetch_btcswp_snapshot(profile)
+ snapshot = fetch_cfi_funding_snapshot(profile)
current_funding = fetch_hl_current_funding_hr(coin)
if current_funding is None:
# Fall back to oracle's r_ema if HL didn't answer.
@@ -303,8 +303,8 @@ def status_cmd(
get_cfi_profile,
)
from cli.hedge_display import hedge_status_block
- from quoting_engine.feeds.seda_oracle import (
- fetch_btcswp_snapshot,
+ from strategies.cfi_funding import (
+ fetch_cfi_funding_snapshot,
fetch_hl_current_funding_hr,
)
@@ -327,7 +327,7 @@ def _refresh():
live.append({"job": h, "snapshot": None, "drift_apy": 0.0, "savings_usd": h.get("cumulative_savings_usd", 0.0)})
continue
try:
- snap = fetch_btcswp_snapshot(profile)
+ snap = fetch_cfi_funding_snapshot(profile)
except Exception:
snap = None
current_hr = fetch_hl_current_funding_hr(h.get("coin", "BTC"))
diff --git a/cli/commands/run.py b/cli/commands/run.py
index 30cb779..49895c0 100644
--- a/cli/commands/run.py
+++ b/cli/commands/run.py
@@ -291,20 +291,4 @@ def _run_anomaly_detector():
if markout_tracker is not None:
engine.markout_tracker = markout_tracker
- # Attach Guard if configured
- if cfg.guard and cfg.guard.get("enabled"):
- from modules.guard_config import GuardConfig, PRESETS
-
- preset_name = cfg.guard.get("preset")
- if preset_name and preset_name in PRESETS:
- guard_cfg = GuardConfig.from_dict(PRESETS[preset_name].to_dict())
- else:
- guard_cfg = GuardConfig.from_dict(cfg.guard)
-
- if "leverage" in cfg.guard:
- guard_cfg.leverage = float(cfg.guard["leverage"])
-
- engine.guard_config = guard_cfg
- typer.echo(f"Guard: enabled (preset={preset_name or 'custom'}, tiers={len(guard_cfg.tiers)})")
-
engine.run(max_ticks=cfg.max_ticks, resume=resume)
diff --git a/cli/engine.py b/cli/engine.py
index 5862685..988d912 100644
--- a/cli/engine.py
+++ b/cli/engine.py
@@ -65,11 +65,7 @@ def __init__(
self._consecutive_timeouts = 0
self._tick_executor = ThreadPoolExecutor(max_workers=1, thread_name_prefix="tick")
- # Optional Guard (composable mode — set via guard_config)
- self.guard_bridge = None # type: ignore[assignment]
- self.guard_config = None # type: ignore[assignment]
-
- # Managed order book (brackets, conditionals, pegged orders)
+# Managed order book (brackets, conditionals, pegged orders)
self.managed_orders = ManagedOrderBook()
# Optional markout tracker (measures fill quality vs anomaly state)
@@ -272,21 +268,6 @@ def _tick(self) -> None:
detector_scores=detector_scores,
)
- # 7b. Lazy Guard init (after first fill establishes a position)
- if self.guard_config is not None and self.guard_bridge is None and fills:
- pos = self.position_tracker.get_agent_position(agent_id, self.instrument)
- if pos.net_qty != ZERO:
- self._init_guard_bridge(pos)
-
- # 7c. Sync Guard position size with tracker (handles partial closes / add-ons)
- if self.guard_bridge is not None and self.guard_bridge.is_active and fills:
- pos = self.position_tracker.get_agent_position(agent_id, self.instrument)
- if pos.net_qty == ZERO:
- # Position fully closed by strategy — deactivate Guard
- self.guard_bridge.mark_closed(snapshot.mid_price, "Position closed by strategy")
- else:
- self.guard_bridge.state.position_size = float(abs(pos.net_qty))
-
# 7d. Update markout windows with current mid price
if self.markout_tracker is not None:
self.markout_tracker.update(snapshot.mid_price, snapshot.timestamp_ms)
@@ -320,105 +301,6 @@ def _tick(self) -> None:
# 10. Log tick
self._log_tick(snapshot, valid_decisions, fills, ok=True)
- # 11. Guard check (composable mode)
- if self.guard_bridge is not None and self.guard_bridge.is_active:
- from modules.trailing_stop import GuardAction
- result = self.guard_bridge.check(snapshot.mid_price)
- _CLOSE_ACTIONS = {GuardAction.CLOSE, GuardAction.PHASE1_TIMEOUT, GuardAction.WEAK_PEAK_CUT}
- if result.action in _CLOSE_ACTIONS:
- _labels = {
- GuardAction.CLOSE: "GUARD CLOSE",
- GuardAction.PHASE1_TIMEOUT: "PHASE1 TIMEOUT (90min no-graduation)",
- GuardAction.WEAK_PEAK_CUT: "WEAK PEAK CUT (45min, peak ROE < 3%)",
- }
- label = _labels.get(result.action, result.action.value)
- elapsed_s = ((time.time() * 1000 - result.state.phase1_start_ts) / 1000
- if result.state.phase1_start_ts else 0)
- log.warning("%s: %s | roe=%.2f%% high_water=%.4f elapsed=%.0fs",
- label, result.reason,
- result.state.current_roe,
- result.state.high_water,
- elapsed_s)
- self._guard_close_position(snapshot)
- self.guard_bridge.mark_closed(snapshot.mid_price, result.reason)
- self._running = False
-
- def _guard_close_position(self, snapshot: MarketSnapshot) -> None:
- """Close position when Guard trailing stop triggers."""
- agent_id = self.strategy.strategy_id
- pos = self.position_tracker.get_agent_position(agent_id, self.instrument)
- if pos.net_qty == ZERO:
- return
-
- close_side = "sell" if pos.net_qty > ZERO else "buy"
- size = float(abs(pos.net_qty))
- if close_side == "sell":
- price = round(float(snapshot.bid) * 0.995, 6)
- else:
- price = round(float(snapshot.ask) * 1.005, 6)
-
- if self.dry_run:
- log.info("[DRY RUN] Guard close: %s %.6f @ %.4f", close_side, size, price)
- return
-
- fill = self.hl.place_order(
- instrument=self.instrument,
- side=close_side,
- size=size,
- price=price,
- tif="Ioc",
- builder=self.builder,
- )
- if fill:
- self.position_tracker.apply_fill(
- agent_id, self.instrument, fill.side,
- fill.quantity, fill.price,
- )
- self.trade_log.append({
- "tick": self.tick_count,
- "oid": fill.oid,
- "instrument": fill.instrument,
- "side": fill.side,
- "price": str(fill.price),
- "quantity": str(fill.quantity),
- "timestamp_ms": fill.timestamp_ms,
- "fee": str(fill.fee),
- "strategy": self.strategy.strategy_id,
- "meta": "guard_close",
- })
- log.info("Guard closed position: %s %s @ %s", fill.side, fill.quantity, fill.price)
- else:
- log.warning("Guard close order did not fill — will retry next tick")
- self._running = True # Keep running to retry
-
- def _init_guard_bridge(self, pos) -> None:
- """Initialize Guard from guard_config after first position is established."""
- from modules.guard_config import GuardConfig
- from modules.guard_bridge import GuardBridge
- from modules.guard_state import GuardState
-
- direction = "long" if pos.net_qty > ZERO else "short"
- self.guard_config.direction = direction
-
- # Auto-compute absolute floor if not set
- entry = float(pos.avg_entry_price)
- if self.guard_config.phase1_absolute_floor == 0.0:
- lev = self.guard_config.leverage
- if direction == "long":
- self.guard_config.phase1_absolute_floor = entry * (1 - 0.03 / lev)
- else:
- self.guard_config.phase1_absolute_floor = entry * (1 + 0.03 / lev)
-
- guard_state = GuardState.new(
- instrument=self.instrument,
- entry_price=entry,
- position_size=float(abs(pos.net_qty)),
- direction=direction,
- )
- self.guard_bridge = GuardBridge(config=self.guard_config, state=guard_state)
- log.info("Guard activated: entry=%.4f size=%.6f dir=%s",
- entry, float(abs(pos.net_qty)), direction)
-
def _close_all_positions(self) -> None:
"""Close all open positions on shutdown to avoid orphaned exposure."""
agent_id = self.strategy.strategy_id
diff --git a/cli/hedge_display.py b/cli/hedge_display.py
index 8db8e33..5e9e267 100644
--- a/cli/hedge_display.py
+++ b/cli/hedge_display.py
@@ -101,7 +101,7 @@ def hedge_proposal_block(proposal, snapshot, *, mainnet: bool = False) -> str:
else "↓" if proposal.wire_drift_per_hour_usd < -0.5
else "↔"
)
- src = "SEDA live" if snapshot.source == "seda" else f"{YELLOW}replay (HL fundingHistory){RESET}"
+ src = f"{GREEN}HL fundingHistory{RESET}"
network = "mainnet" if mainnet else "testnet"
lines = [
diff --git a/cli/main.py b/cli/main.py
index a928b7a..314d9d3 100644
--- a/cli/main.py
+++ b/cli/main.py
@@ -23,12 +23,7 @@
from cli.commands.trade import trade_cmd
from cli.commands.account import account_cmd
from cli.commands.strategies import strategies_cmd
-from cli.commands.guard import guard_app
-from cli.commands.radar import radar_app
-from cli.commands.pulse import pulse_app
-from cli.commands.apex import apex_app
from cli.commands.builder import builder_app
-from cli.commands.reflect import reflect_app
from cli.commands.wallet import wallet_app
from cli.commands.setup import setup_app
from cli.commands.mcp import mcp_app
@@ -54,12 +49,7 @@
app.command("emergency-close", help="Cancel all orders and market-close all positions")(emergency_close_cmd)
app.command("order-status", help="Look up a single order by oid")(order_status_cmd)
app.command("funding", help="Show current funding rates")(funding_cmd)
-app.add_typer(guard_app, name="guard", help="Guard trailing stop system")
-app.add_typer(radar_app, name="radar", help="Radar — screen HL perps for setups")
-app.add_typer(pulse_app, name="pulse", help="Pulse — detect assets with capital inflow")
-app.add_typer(apex_app, name="apex", help="APEX — autonomous multi-slot trading")
app.add_typer(builder_app, name="builder", help="Builder fee — revenue collection on trades")
-app.add_typer(reflect_app, name="reflect", help="Reflect — performance review and self-improvement")
app.add_typer(wallet_app, name="wallet", help="Encrypted keystore wallet management")
app.add_typer(setup_app, name="setup", help="Environment validation and setup")
app.add_typer(mcp_app, name="mcp", help="MCP server — AI agent tool discovery")
diff --git a/cli/mcp_server.py b/cli/mcp_server.py
index e360fcf..d2476ad 100644
--- a/cli/mcp_server.py
+++ b/cli/mcp_server.py
@@ -1,7 +1,7 @@
"""MCP server for agent-cli — exposes trading tools via Model Context Protocol.
Fast tools (account, strategies, builder, wallet, setup) call Python directly.
-Long-running tools (run_strategy, apex_run, radar, reflect) use subprocess.
+Long-running tools (run_strategy) use subprocess.
Every tool carries MCP annotations (readOnlyHint / destructiveHint) so MCP
clients can distinguish a harmless read from a fund-moving action. The
@@ -27,18 +27,17 @@
# Tools that only read state (no side effects, safe to call freely).
_READ_ONLY_TOOLS = {
"strategies", "builder_status", "wallet_list", "setup_check",
- "account", "status", "apex_status",
+ "account", "status",
"funding_hedge_propose", "funding_hedge_backtest",
"agent_memory", "trade_journal", "judge_report", "obsidian_context",
"order_status", "funding_rates",
}
# Tools that move funds or cancel/close live orders/positions — handle with care.
_DESTRUCTIVE_TOOLS = {
- "trade", "run_strategy", "apex_run", "funding_hedge_execute",
+ "trade", "run_strategy", "funding_hedge_execute",
"schedule_cancel", "emergency_close_all",
}
-# Everything else (wallet_auto, radar_run, reflect_run) is
-# state-changing-but-safe: neither a pure read nor fund-destructive.
+# Everything else (wallet_auto) is state-changing-but-safe.
_TRUSTED_CONTEXT_SECRET_ENVS = (
"NUNCHI_RUNNER_CONTEXT_SECRET",
@@ -357,9 +356,9 @@ def _ann(name: str, title: str):
mcp = FastMCP(
"yex-trader",
instructions=(
- "Autonomous Hyperliquid trading CLI — 14 strategies, APEX orchestrator, "
- "REFLECT reviews. Always confirm details with the user before calling "
- "destructive tools (trade, run_strategy, apex_run, funding_hedge_execute, "
+ "CFI v2 funding-rate hedge on Hyperliquid — hl hedge propose/execute/status/auto. "
+ "Always confirm details with the user before calling "
+ "destructive tools (trade, run_strategy, funding_hedge_execute, "
"schedule_cancel, emergency_close_all). "
"funding_hedge_execute requires confirmed=true. "
"emergency_close_all requires confirm=true."
@@ -627,75 +626,6 @@ def run_strategy(
env_overrides=env_overrides,
)
- @mcp.tool(**_ann("radar_run", "Run radar scan"))
- def radar_run(mock: bool = False, ctx: FastMCPContext = None) -> str:
- """Run opportunity radar — screen HL perps for trading setups."""
- args = ["radar", "once"]
- if mock:
- args.append("--mock")
- return _run_hl(*args, timeout=60, env_overrides=_request_env(ctx))
-
- @mcp.tool(**_ann("apex_status", "APEX status"))
- def apex_status(ctx: FastMCPContext = None) -> str:
- """Get APEX orchestrator status (slots, positions, daily PnL)."""
- return _run_hl("apex", "status", env_overrides=_request_env(ctx))
-
- @mcp.tool(**_ann("apex_run", "Run APEX"))
- def apex_run(
- mock: bool = False,
- max_ticks: Optional[int] = None,
- preset: str = "default",
- mainnet: bool = False,
- confirmed: bool = False,
- ctx: FastMCPContext = None,
- ) -> str:
- """Start APEX multi-slot orchestrator. WARNING: places real orders unless mock.
-
- Args:
- mock: Use mock data
- max_ticks: Stop after N ticks
- preset: Strategy preset (default, conservative, aggressive)
- mainnet: Use mainnet
- confirmed: Explicit confirmation for hosted gateway sessions that require it.
- """
- env_overrides = _request_env(ctx)
- effective_max_ticks = max_ticks if max_ticks is not None else _trusted_max_ticks(env_overrides)
- error = _context_limit_error(
- "apex_run",
- env_overrides,
- mainnet=mainnet,
- max_ticks=effective_max_ticks,
- confirmed=confirmed,
- require_signing=not mock,
- )
- if error:
- return _json_error(error)
-
- args = ["apex", "run", "--preset", preset]
- if mock:
- args.append("--mock")
- if effective_max_ticks is not None:
- args.extend(["--max-ticks", str(effective_max_ticks)])
- if mainnet:
- args.append("--mainnet")
- return _run_hl(
- *args,
- timeout=max(120, (effective_max_ticks or 10) * 60 + 30),
- env_overrides=env_overrides,
- )
-
- @mcp.tool(**_ann("reflect_run", "Run reflect review"))
- def reflect_run(since: Optional[str] = None, ctx: FastMCPContext = None) -> str:
- """Run REFLECT performance review — analyze trades and generate report.
-
- Args:
- since: Start date for analysis (YYYY-MM-DD). Default: since last report.
- """
- args = ["reflect", "run"]
- if since:
- args.extend(["--since", since])
- return _run_hl(*args, env_overrides=_request_env(ctx))
-
# ------------------------------------------------------------------
# Safety tools — dead-man's switch + panic close
# ------------------------------------------------------------------
diff --git a/pyproject.toml b/pyproject.toml
index f567620..97a45fb 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -46,7 +46,7 @@ Repository = "https://github.com/Nunchi-trade/agent-cli"
[tool.pytest.ini_options]
pythonpath = ["."]
-norecursedirs = ["_archive", ".*", "build", "dist"]
+norecursedirs = ["_archive", "archive", ".*", "build", "dist"]
[tool.mypy]
python_version = "3.10"
@@ -56,4 +56,4 @@ disallow_untyped_defs = false
ignore_missing_imports = true
[tool.setuptools.packages.find]
-include = ["cli*", "strategies*", "sdk*", "common*", "parent*", "modules*", "skills*", "quoting_engine*"]
+include = ["cli*", "strategies*", "sdk*", "common*", "parent*", "modules*", "skills*"]
diff --git a/scripts/entrypoint.py b/scripts/entrypoint.py
index 733309a..a500158 100644
--- a/scripts/entrypoint.py
+++ b/scripts/entrypoint.py
@@ -35,9 +35,6 @@
"setup_check",
"account",
"status",
- "apex_status",
- "radar_run",
- "reflect_run",
"agent_memory",
"trade_journal",
"judge_report",
@@ -51,7 +48,6 @@
"wallet_auto",
"trade",
"run_strategy",
- "apex_run",
"funding_hedge_execute",
"schedule_cancel",
"emergency_close_all",
@@ -79,7 +75,7 @@ def do_GET(self):
elif self.path == "/status":
try:
result = subprocess.run(
- [sys.executable, "-m", "cli.main", "apex", "status"],
+ [sys.executable, "-m", "cli.main", "status"],
capture_output=True, text=True, timeout=10,
)
output = result.stdout.strip() or result.stderr.strip() or "(no output)"
@@ -306,41 +302,10 @@ def build_command() -> list[str]:
py = [sys.executable, "-m", "cli.main"]
if mode in ("apex", "wolf"):
- cmd = py + ["apex", "run"]
- preset = os.environ.get("APEX_PRESET")
- if preset:
- cmd += ["--preset", preset]
- budget = os.environ.get("APEX_BUDGET")
- if budget:
- cmd += ["--budget", budget]
- slots = os.environ.get("APEX_SLOTS")
- if slots:
- cmd += ["--slots", slots]
- leverage = os.environ.get("APEX_LEVERAGE")
- if leverage:
- cmd += ["--leverage", leverage]
- tick = os.environ.get("TICK_INTERVAL")
- if tick:
- cmd += ["--tick", tick]
- # Restrict the agent's pulse/radar scans and entries to a set of
- # markets. Critical for PR-3 dedicated-wallet mode where the agent
- # is funded on a HIP-3 dex (e.g. yex) and must NOT scan universal
- # HL perps that it has no collateral on. Without this, agents
- # scan 207+ universal markets and produce zero entries even though
- # they hold $1000 in their yex clearinghouse.
- allowed = os.environ.get("ALLOWED_INSTRUMENTS")
- if allowed:
- cmd += ["--markets", allowed]
- strategy_names = os.environ.get("STRATEGY_NAMES")
- if strategy_names:
- cmd += ["--strategy-names", strategy_names]
- base_dir = os.environ.get("DATA_DIR", "/data")
- cmd += ["--data-dir", f"{base_dir}/apex"]
- if os.environ.get("HL_TESTNET", "true").lower() == "false":
- cmd.append("--mainnet")
- return cmd
+ log.warning("RUN_MODE=%s is deprecated; use strategy or mcp. Falling back to cfi_hedge.", mode)
+ mode = "strategy"
- elif mode == "strategy":
+ if mode == "strategy":
strategy = os.environ.get("STRATEGY", "cfi_hedge")
instrument = os.environ.get("INSTRUMENT", "ETH-PERP")
tick = os.environ.get("TICK_INTERVAL", "10")
@@ -353,7 +318,7 @@ def build_command() -> list[str]:
return py + ["mcp", "serve", "--transport", "sse"]
else:
- log.error("Unknown RUN_MODE: %s. Use apex, wolf, strategy, or mcp.", mode)
+ log.error("Unknown RUN_MODE: %s. Use strategy or mcp.", mode)
sys.exit(1)
@@ -424,18 +389,7 @@ def call_mcp_tool(name: str, arguments: dict[str, Any], headers: Any) -> str:
if name == "status":
return _run_hl("status", env_overrides=env_overrides)
if name == "apex_status":
- return _run_hl("apex", "status", env_overrides=env_overrides)
- if name == "radar_run":
- cmd = ["radar", "once"]
- if _bool_arg(arguments, "mock"):
- cmd.append("--mock")
- return _run_hl(*cmd, timeout=60, env_overrides=env_overrides)
- if name == "reflect_run":
- cmd = ["reflect", "run"]
- since = _str_arg(arguments, "since")
- if since:
- cmd.extend(["--since", since])
- return _run_hl(*cmd, env_overrides=env_overrides)
+ return _run_hl("status", env_overrides=env_overrides)
if name == "order_status":
oid = _str_arg(arguments, "oid")
if not oid:
@@ -537,32 +491,6 @@ def call_mcp_tool(name: str, arguments: dict[str, Any], headers: Any) -> str:
cmd.append("--mainnet")
return _run_hl(*cmd, timeout=max(60, (effective_max_ticks or 10) * tick + 30), env_overrides=env_overrides)
- if name == "apex_run":
- mock = _bool_arg(arguments, "mock")
- max_ticks = _int_arg(arguments, "max_ticks")
- preset = _str_arg(arguments, "preset") or "default"
- mainnet = _bool_arg(arguments, "mainnet")
- confirmed = _bool_arg(arguments, "confirmed")
- effective_max_ticks = max_ticks if max_ticks is not None else _trusted_max_ticks(env_overrides)
- error = _context_limit_error(
- "apex_run",
- env_overrides,
- mainnet=mainnet,
- max_ticks=effective_max_ticks,
- confirmed=confirmed,
- require_signing=not mock,
- )
- if error:
- return _json_error(error)
- cmd = ["apex", "run", "--preset", preset]
- if mock:
- cmd.append("--mock")
- if effective_max_ticks is not None:
- cmd.extend(["--max-ticks", str(effective_max_ticks)])
- if mainnet:
- cmd.append("--mainnet")
- return _run_hl(*cmd, timeout=max(120, (effective_max_ticks or 10) * 60 + 30), env_overrides=env_overrides)
-
if name == "funding_hedge_execute":
coin = _str_arg(arguments, "coin") or "BTC"
dry_run = _bool_arg(arguments, "dry_run")
diff --git a/scripts/validate_agent_cli.py b/scripts/validate_agent_cli.py
index b08ca45..704708b 100644
--- a/scripts/validate_agent_cli.py
+++ b/scripts/validate_agent_cli.py
@@ -130,7 +130,6 @@ def base_cases(python: str, quick_pytest: bool) -> list[TestCase]:
"strategies",
"modules",
"skills",
- "quoting_engine",
"scripts",
],
python,
@@ -157,11 +156,9 @@ def base_cases(python: str, quick_pytest: bool) -> list[TestCase]:
"setup",
"wallet",
"builder",
- "radar",
- "pulse",
- "apex",
- "guard",
- "reflect",
+ "hedge",
+ "margin",
+ "trading",
"journal",
"keys",
"mcp",
@@ -181,7 +178,7 @@ def base_cases(python: str, quick_pytest: bool) -> list[TestCase]:
def node_cases() -> list[TestCase]:
cases: list[TestCase] = []
- for path in sorted((REPO_ROOT / "deploy").glob("*/src/*")):
+ for path in sorted((REPO_ROOT / "_archive" / "deploy").glob("*/src/*")):
if path.suffix not in {".js", ".mjs"}:
continue
cases.append(
@@ -259,67 +256,6 @@ def e2e_cases(python: str, data_root: Path) -> list[TestCase]:
timeout_s=60,
profiles=("e2e", "production"),
),
- TestCase(
- name="radar_once_mock",
- stage="e2e_mock",
- command=python_cmd(
- [
- "-m",
- "cli.main",
- "radar",
- "once",
- "--mock",
- "--top-n",
- "3",
- "--min-volume",
- "0",
- "--score-threshold",
- "0",
- "--data-dir",
- str(data_root / "radar"),
- ],
- python,
- ),
- timeout_s=60,
- profiles=("e2e", "production"),
- ),
- TestCase(
- name="pulse_once_mock",
- stage="e2e_mock",
- command=python_cmd(
- [
- "-m",
- "cli.main",
- "pulse",
- "once",
- "--mock",
- "--min-volume",
- "0",
- "--data-dir",
- str(data_root / "pulse"),
- ],
- python,
- ),
- timeout_s=60,
- profiles=("e2e", "production"),
- ),
- TestCase(
- name="apex_once_mock",
- stage="e2e_mock",
- command=python_cmd(
- ["-m", "cli.main", "apex", "once", "--mock", "--data-dir", str(data_root / "apex")],
- python,
- ),
- timeout_s=90,
- profiles=("e2e", "production"),
- ),
- TestCase(
- name="apex_status_after_mock",
- stage="e2e_mock",
- command=python_cmd(["-m", "cli.main", "apex", "status", "--data-dir", str(data_root / "apex")], python),
- timeout_s=30,
- profiles=("e2e", "production"),
- ),
TestCase(
name="status_reader_json_contracts",
stage="api_contract",
@@ -350,7 +286,7 @@ def status_reader_contract_code(data_root: Path) -> str:
return (
"import json, subprocess, sys; "
f"data_dir={data}; "
- "cmds=['status','strategies','trades','reflect','radar','journal']; "
+ "cmds=['status','strategies','trades','journal']; "
"seen={}; "
"\nfor cmd in cmds:\n"
" args=[sys.executable,'-m','cli.api.status_reader',cmd,'--data-dir',data_dir]\n"
@@ -432,29 +368,6 @@ def production_cases(python: str, mainnet: bool, live_data_root: Path) -> list[T
profiles=("production",),
live_probe=True,
),
- TestCase(
- name="live_radar_readonly_scan",
- stage="production_readonly",
- command=python_cmd(
- [
- "-m",
- "cli.main",
- "radar",
- "once",
- *network_flag,
- "--top-n",
- "5",
- "--score-threshold",
- "9999",
- "--data-dir",
- str(live_data_root / "radar"),
- ],
- python,
- ),
- timeout_s=90,
- profiles=("production",),
- live_probe=True,
- ),
]
diff --git a/strategies/cfi_funding.py b/strategies/cfi_funding.py
new file mode 100644
index 0000000..f627be8
--- /dev/null
+++ b/strategies/cfi_funding.py
@@ -0,0 +1,146 @@
+"""CFI v2 funding inputs from Hyperliquid only.
+
+No SEDA/oracle dependency — hedge math stays in `strategies/cfi_hedge.py`.
+K2 fixed leg and r_ema are replayed from HL `fundingHistory`; current funding
+from `metaAndAssetCtxs`.
+"""
+from __future__ import annotations
+
+import logging
+import os
+import time
+from dataclasses import dataclass
+from typing import Literal, Optional
+
+import requests
+
+from strategies.cfi_hedge import (
+ BTCSWP_PROFILE,
+ CFIAssetProfile,
+ FundingRateSample,
+ compute_k2_from_history,
+)
+
+log = logging.getLogger(__name__)
+
+HL_INFO_URL_DEFAULT = "https://api.hyperliquid.xyz/info"
+
+
+def _hl_info_url() -> str:
+ return os.environ.get("HL_INFO_URL", HL_INFO_URL_DEFAULT)
+
+
+@dataclass(frozen=True)
+class CfiFundingSnapshot:
+ """K2 + r_ema computed from HL funding history."""
+
+ source: Literal["hl"]
+ timestamp_iso: str
+ timestamp_ms: int
+ oracle_px: Optional[float]
+ k_fixed_hr: float
+ r_ema_hr: float
+ cfi: Optional[float]
+
+
+def _fetch_funding_history(
+ coin: str,
+ lookback_hours: int,
+ *,
+ timeout_s: float = 10.0,
+) -> list[dict]:
+ """Pull HL `fundingHistory` for a coin over the lookback window."""
+ end_time = int(time.time() * 1000)
+ start_time = end_time - lookback_hours * 60 * 60 * 1000
+ resp = requests.post(
+ _hl_info_url(),
+ json={
+ "type": "fundingHistory",
+ "coin": coin,
+ "startTime": start_time,
+ "endTime": end_time,
+ },
+ timeout=timeout_s,
+ )
+ resp.raise_for_status()
+ return resp.json() or []
+
+
+def fetch_hl_current_funding_hr(
+ coin: str,
+ *,
+ timeout_s: float = 10.0,
+) -> Optional[float]:
+ """Predicted current hourly funding rate for an HL coin."""
+ try:
+ resp = requests.post(
+ _hl_info_url(),
+ json={"type": "metaAndAssetCtxs"},
+ timeout=timeout_s,
+ )
+ resp.raise_for_status()
+ data = resp.json()
+ universe = data[0]["universe"]
+ ctxs = data[1]
+ for meta, ctx in zip(universe, ctxs):
+ if meta.get("name") == coin:
+ return float(ctx.get("funding", 0))
+ return None
+ except Exception as e:
+ log.warning("cfi_funding: fetch_hl_current_funding_hr(%s) failed: %s", coin, e)
+ return None
+
+
+def replay_k2_from_hl(
+ profile: CFIAssetProfile = BTCSWP_PROFILE,
+ *,
+ lookback_hours: int = 168,
+ timeout_s: float = 10.0,
+) -> CfiFundingSnapshot:
+ """Compute K2 + r_ema locally from HL `fundingHistory`."""
+ hist = _fetch_funding_history(
+ profile.hl_coin,
+ lookback_hours,
+ timeout_s=timeout_s,
+ )
+ samples = [
+ FundingRateSample(
+ funding_rate=float(e["fundingRate"]),
+ time=int(e["time"]),
+ )
+ for e in hist
+ ]
+ k = compute_k2_from_history(samples, profile)
+
+ if samples:
+ r_ema = samples[0].funding_rate
+ for s in samples:
+ r_ema = (1.0 - profile.k2_beta) * r_ema + profile.k2_beta * s.funding_rate
+ else:
+ r_ema = profile.fixed_leg_initial
+
+ now_ms = int(time.time() * 1000)
+ now_iso = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(now_ms / 1000))
+ return CfiFundingSnapshot(
+ source="hl",
+ timestamp_iso=now_iso,
+ timestamp_ms=now_ms,
+ oracle_px=None,
+ k_fixed_hr=k,
+ r_ema_hr=r_ema,
+ cfi=None,
+ )
+
+
+def fetch_cfi_funding_snapshot(
+ profile: CFIAssetProfile = BTCSWP_PROFILE,
+ *,
+ timeout_s: float = 10.0,
+) -> CfiFundingSnapshot:
+ """Live K2 inputs from HL funding history only."""
+ return replay_k2_from_hl(profile, timeout_s=timeout_s)
+
+
+# Back-compat aliases for callers migrating off seda_oracle naming.
+BTCSWPOracleSnapshot = CfiFundingSnapshot
+fetch_btcswp_snapshot = fetch_cfi_funding_snapshot
diff --git a/strategies/cfi_hedge.py b/strategies/cfi_hedge.py
index 1e42e3c..2b050b6 100644
--- a/strategies/cfi_hedge.py
+++ b/strategies/cfi_hedge.py
@@ -140,7 +140,7 @@ def apy_to_hourly(apy: float) -> float:
return apy / HOURS_PER_YEAR
-# ─── K2 EMA replay (fallback when SEDA oracle is unreachable) ───────────────
+# ─── K2 EMA replay from HL fundingHistory ───────────────────────────────────
@dataclass(frozen=True)
diff --git a/tests/_archive/README.md b/tests/_archive/README.md
index 91a9979..d9b31b4 100644
--- a/tests/_archive/README.md
+++ b/tests/_archive/README.md
@@ -1,6 +1,11 @@
-# Archived strategy tests
+# Archived strategy and quoting-engine tests
-Tests for legacy strategies archived on **2026-07-02**. Not collected by default pytest runs
+Tests for legacy strategies and the quoting engine archived on **2026-07-02**. Not collected by default pytest runs
(`norecursedirs` excludes `_archive`).
-Run manually if needed: `pytest tests/_archive/ -v`
+Run manually if needed:
+
+```bash
+pytest tests/_archive/ -v
+PYTHONPATH=_archive:. pytest tests/_archive/quoting_engine/ -v
+```
diff --git a/tests/quoting_engine/conftest.py b/tests/_archive/quoting_engine/conftest.py
similarity index 78%
rename from tests/quoting_engine/conftest.py
rename to tests/_archive/quoting_engine/conftest.py
index 4339da0..0fe18ea 100644
--- a/tests/quoting_engine/conftest.py
+++ b/tests/_archive/quoting_engine/conftest.py
@@ -1,5 +1,14 @@
"""Shared fixtures for quoting engine tests."""
+import sys
+from pathlib import Path
+
import pytest
+
+# Archived package lives under repo-root/_archive/quoting_engine.
+_archive_root = Path(__file__).resolve().parents[2] / "_archive"
+if str(_archive_root) not in sys.path:
+ sys.path.insert(0, str(_archive_root))
+
from quoting_engine.config import (
MarketConfig, FairValueWeights, SpreadParams,
LadderParams, SkewParams,
diff --git a/tests/quoting_engine/test_qe_config.py b/tests/_archive/quoting_engine/test_qe_config.py
similarity index 100%
rename from tests/quoting_engine/test_qe_config.py
rename to tests/_archive/quoting_engine/test_qe_config.py
diff --git a/tests/quoting_engine/test_qe_disagreement.py b/tests/_archive/quoting_engine/test_qe_disagreement.py
similarity index 100%
rename from tests/quoting_engine/test_qe_disagreement.py
rename to tests/_archive/quoting_engine/test_qe_disagreement.py
diff --git a/tests/quoting_engine/test_qe_engine.py b/tests/_archive/quoting_engine/test_qe_engine.py
similarity index 100%
rename from tests/quoting_engine/test_qe_engine.py
rename to tests/_archive/quoting_engine/test_qe_engine.py
diff --git a/tests/quoting_engine/test_qe_event_schedule_calendar.py b/tests/_archive/quoting_engine/test_qe_event_schedule_calendar.py
similarity index 100%
rename from tests/quoting_engine/test_qe_event_schedule_calendar.py
rename to tests/_archive/quoting_engine/test_qe_event_schedule_calendar.py
diff --git a/tests/quoting_engine/test_qe_fair_value.py b/tests/_archive/quoting_engine/test_qe_fair_value.py
similarity index 100%
rename from tests/quoting_engine/test_qe_fair_value.py
rename to tests/_archive/quoting_engine/test_qe_fair_value.py
diff --git a/tests/quoting_engine/test_qe_feeds_base.py b/tests/_archive/quoting_engine/test_qe_feeds_base.py
similarity index 100%
rename from tests/quoting_engine/test_qe_feeds_base.py
rename to tests/_archive/quoting_engine/test_qe_feeds_base.py
diff --git a/tests/quoting_engine/test_qe_funding_boundary.py b/tests/_archive/quoting_engine/test_qe_funding_boundary.py
similarity index 100%
rename from tests/quoting_engine/test_qe_funding_boundary.py
rename to tests/_archive/quoting_engine/test_qe_funding_boundary.py
diff --git a/tests/quoting_engine/test_qe_funding_rate_feed.py b/tests/_archive/quoting_engine/test_qe_funding_rate_feed.py
similarity index 100%
rename from tests/quoting_engine/test_qe_funding_rate_feed.py
rename to tests/_archive/quoting_engine/test_qe_funding_rate_feed.py
diff --git a/tests/quoting_engine/test_qe_fv_band.py b/tests/_archive/quoting_engine/test_qe_fv_band.py
similarity index 100%
rename from tests/quoting_engine/test_qe_fv_band.py
rename to tests/_archive/quoting_engine/test_qe_fv_band.py
diff --git a/tests/quoting_engine/test_qe_inventory.py b/tests/_archive/quoting_engine/test_qe_inventory.py
similarity index 100%
rename from tests/quoting_engine/test_qe_inventory.py
rename to tests/_archive/quoting_engine/test_qe_inventory.py
diff --git a/tests/quoting_engine/test_qe_inventory_caps.py b/tests/_archive/quoting_engine/test_qe_inventory_caps.py
similarity index 100%
rename from tests/quoting_engine/test_qe_inventory_caps.py
rename to tests/_archive/quoting_engine/test_qe_inventory_caps.py
diff --git a/tests/quoting_engine/test_qe_ladder.py b/tests/_archive/quoting_engine/test_qe_ladder.py
similarity index 100%
rename from tests/quoting_engine/test_qe_ladder.py
rename to tests/_archive/quoting_engine/test_qe_ladder.py
diff --git a/tests/quoting_engine/test_qe_liq_advanced.py b/tests/_archive/quoting_engine/test_qe_liq_advanced.py
similarity index 100%
rename from tests/quoting_engine/test_qe_liq_advanced.py
rename to tests/_archive/quoting_engine/test_qe_liq_advanced.py
diff --git a/tests/quoting_engine/test_qe_metrics.py b/tests/_archive/quoting_engine/test_qe_metrics.py
similarity index 100%
rename from tests/quoting_engine/test_qe_metrics.py
rename to tests/_archive/quoting_engine/test_qe_metrics.py
diff --git a/tests/quoting_engine/test_qe_microprice.py b/tests/_archive/quoting_engine/test_qe_microprice.py
similarity index 100%
rename from tests/quoting_engine/test_qe_microprice.py
rename to tests/_archive/quoting_engine/test_qe_microprice.py
diff --git a/tests/quoting_engine/test_qe_oracle_monitor.py b/tests/_archive/quoting_engine/test_qe_oracle_monitor.py
similarity index 100%
rename from tests/quoting_engine/test_qe_oracle_monitor.py
rename to tests/_archive/quoting_engine/test_qe_oracle_monitor.py
diff --git a/tests/quoting_engine/test_qe_regime.py b/tests/_archive/quoting_engine/test_qe_regime.py
similarity index 100%
rename from tests/quoting_engine/test_qe_regime.py
rename to tests/_archive/quoting_engine/test_qe_regime.py
diff --git a/tests/quoting_engine/test_qe_spread.py b/tests/_archive/quoting_engine/test_qe_spread.py
similarity index 100%
rename from tests/quoting_engine/test_qe_spread.py
rename to tests/_archive/quoting_engine/test_qe_spread.py
diff --git a/tests/quoting_engine/test_qe_toxicity.py b/tests/_archive/quoting_engine/test_qe_toxicity.py
similarity index 100%
rename from tests/quoting_engine/test_qe_toxicity.py
rename to tests/_archive/quoting_engine/test_qe_toxicity.py
diff --git a/tests/quoting_engine/test_qe_toxicity_tiered.py b/tests/_archive/quoting_engine/test_qe_toxicity_tiered.py
similarity index 100%
rename from tests/quoting_engine/test_qe_toxicity_tiered.py
rename to tests/_archive/quoting_engine/test_qe_toxicity_tiered.py
diff --git a/tests/quoting_engine/test_qe_vol_estimator.py b/tests/_archive/quoting_engine/test_qe_vol_estimator.py
similarity index 100%
rename from tests/quoting_engine/test_qe_vol_estimator.py
rename to tests/_archive/quoting_engine/test_qe_vol_estimator.py
diff --git a/tests/test_builder_fee.py b/tests/test_builder_fee.py
index d001a39..8812616 100644
--- a/tests/test_builder_fee.py
+++ b/tests/test_builder_fee.py
@@ -170,23 +170,3 @@ def test_no_builder_when_none(self):
call_kwargs = mock_hl.place_order.call_args
assert call_kwargs.kwargs.get("builder") is None
-
-# ---------------------------------------------------------------------------
-# ApexRunner accepts builder
-# ---------------------------------------------------------------------------
-
-class TestApexRunnerBuilder:
- def test_apex_runner_stores_builder(self):
- from skills.apex.scripts.standalone_runner import ApexRunner
-
- mock_hl = MagicMock()
- builder_info = {"b": "0xAPEX", "f": 10}
- runner = ApexRunner(hl=mock_hl, builder=builder_info)
- assert runner.builder == builder_info
-
- def test_apex_runner_builder_default_none(self):
- from skills.apex.scripts.standalone_runner import ApexRunner
-
- mock_hl = MagicMock()
- runner = ApexRunner(hl=mock_hl)
- assert runner.builder is None
diff --git a/tests/test_entrypoint.py b/tests/test_entrypoint.py
index 1456700..6206066 100644
--- a/tests/test_entrypoint.py
+++ b/tests/test_entrypoint.py
@@ -27,56 +27,22 @@ def test_default_mode_is_mcp(self, monkeypatch):
cmd = build_command()
assert cmd == [sys.executable, "-m", "cli.main", "mcp", "serve", "--transport", "sse"]
- def test_apex_mode_default(self, monkeypatch):
+ def test_apex_mode_falls_back_to_strategy(self, monkeypatch):
monkeypatch.setenv("RUN_MODE", "apex")
- monkeypatch.delenv("APEX_PRESET", raising=False)
- monkeypatch.delenv("APEX_BUDGET", raising=False)
- monkeypatch.delenv("APEX_SLOTS", raising=False)
- monkeypatch.delenv("APEX_LEVERAGE", raising=False)
- monkeypatch.delenv("TICK_INTERVAL", raising=False)
+ monkeypatch.setenv("STRATEGY", "cfi_hedge")
+ monkeypatch.setenv("INSTRUMENT", "BTC-PERP")
+ monkeypatch.setenv("TICK_INTERVAL", "10")
monkeypatch.setenv("HL_TESTNET", "true")
cmd = build_command()
- assert cmd[:3] == [sys.executable, "-m", "cli.main"]
- assert "apex" in cmd
- assert "run" in cmd
- assert "--data-dir" in cmd
- assert "--mainnet" not in cmd
-
- def test_apex_mode_with_all_options(self, monkeypatch):
- monkeypatch.setenv("RUN_MODE", "apex")
- monkeypatch.setenv("APEX_PRESET", "aggressive")
- monkeypatch.setenv("APEX_BUDGET", "1000")
- monkeypatch.setenv("APEX_SLOTS", "5")
- monkeypatch.setenv("APEX_LEVERAGE", "10")
- monkeypatch.setenv("TICK_INTERVAL", "30")
- monkeypatch.setenv("HL_TESTNET", "false")
-
- cmd = build_command()
- assert "--preset" in cmd
- assert "aggressive" in cmd
- assert "--budget" in cmd
- assert "1000" in cmd
- assert "--slots" in cmd
- assert "5" in cmd
- assert "--leverage" in cmd
- assert "10" in cmd
- assert "--tick" in cmd
- assert "30" in cmd
- assert "--mainnet" in cmd
+ assert "run" in cmd and "cfi_hedge" in cmd and "apex" not in cmd
- def test_wolf_mode(self, monkeypatch):
+ def test_wolf_mode_falls_back_to_strategy(self, monkeypatch):
monkeypatch.setenv("RUN_MODE", "wolf")
+ monkeypatch.setenv("STRATEGY", "cfi_hedge")
monkeypatch.setenv("HL_TESTNET", "true")
- monkeypatch.delenv("APEX_PRESET", raising=False)
- monkeypatch.delenv("APEX_BUDGET", raising=False)
- monkeypatch.delenv("APEX_SLOTS", raising=False)
- monkeypatch.delenv("APEX_LEVERAGE", raising=False)
- monkeypatch.delenv("TICK_INTERVAL", raising=False)
-
cmd = build_command()
- assert "apex" in cmd
- assert "run" in cmd
+ assert "run" in cmd and "cfi_hedge" in cmd and "apex" not in cmd
def test_strategy_mode(self, monkeypatch):
monkeypatch.setenv("RUN_MODE", "strategy")
diff --git a/tests/test_mcp_annotations.py b/tests/test_mcp_annotations.py
index bf868c6..5d3ff5c 100644
--- a/tests/test_mcp_annotations.py
+++ b/tests/test_mcp_annotations.py
@@ -16,7 +16,6 @@ def test_destructive_set_covers_fund_movers():
for name in (
"trade",
"run_strategy",
- "apex_run",
"funding_hedge_execute",
"schedule_cancel",
"emergency_close_all",
From e504bf23ea996d4763c0638785cabdcd674194f3 Mon Sep 17 00:00:00 2001
From: JaeLeex
Date: Fri, 3 Jul 2026 12:59:51 -0400
Subject: [PATCH 2/2] docs: mark archived operator stack as legacy
Co-authored-by: Cursor
---
README.md | 299 +++++-------------------------------------------------
1 file changed, 26 insertions(+), 273 deletions(-)
diff --git a/README.md b/README.md
index 6834549..881a8cb 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@
-
+
@@ -81,7 +81,6 @@ export HL_TESTNET=false
hl builder approve --mainnet
hl hedge propose BTC
hl run cfi_hedge -i BTCSWP-PARA --mock --max-ticks 3 --mainnet
-hl apex run --mainnet
```
See [Markets & Instruments](#markets--instruments) for native perps, Paragon BTCSWP, and YEX symbols.
@@ -171,28 +170,18 @@ MCP tools: `funding_hedge_propose`, `funding_hedge_execute`, `funding_hedge_back
## Skills
-Built on the open [Agent Skills](https://agentskills.io) standard. Each skill is self-contained with instructions, scripts, and references.
+Built on the open [Agent Skills](https://agentskills.io) standard. The active tree ships the onboarding skill for first-time local setup. The legacy operator skills were archived with their commands and modules under `_archive/skills/`.
| Skill | What it does | Install |
|-------|-------------|---------|
| **[Onboard](#onboard)** | Step-by-step first-time setup — from zero to first trade. Decision trees, verification at each step, error recovery. | [`SKILL.md`](skills/onboard/SKILL.md) |
-| **[APEX Strategy](#apex--autonomous-multi-slot-strategy)** | Fully autonomous 2-3 slot trading. Composes Radar + Pulse + Guard. Proven on testnet: signal detection, entry, trailing stop, exit. | [`SKILL.md`](skills/apex/SKILL.md) |
-| **[Radar](#radar--opportunity-radar)** | 4-stage funnel screening all HL perps. Scores 0-400 across market structure, technicals, funding, and BTC macro. | [`SKILL.md`](skills/radar/SKILL.md) |
-| **[Pulse](#pulse--emerging-pulse-detector)** | Detects sudden capital inflow via OI delta, volume surge, funding flips. IMMEDIATE signals at 100 confidence. | [`SKILL.md`](skills/pulse/SKILL.md) |
-| **[Guard (Dynamic Stop Loss)](#guard--dynamic-stop-loss)** | 2-phase trailing stop with tiered profit-locking. ROE-based triggers that auto-account for leverage. | [`SKILL.md`](skills/guard/SKILL.md) |
-| **[REFLECT](#reflect--performance-review)** | Nightly self-improvement loop. Analyzes every trade, finds patterns, generates actionable recommendations. | [`SKILL.md`](skills/reflect/SKILL.md) |
-### Install a skill (agents)
+### Install the active skill
Grab the raw URL and go:
```
https://raw.githubusercontent.com/Nunchi-trade/agent-cli/main/skills/onboard/SKILL.md
-https://raw.githubusercontent.com/Nunchi-trade/agent-cli/main/skills/apex/SKILL.md
-https://raw.githubusercontent.com/Nunchi-trade/agent-cli/main/skills/radar/SKILL.md
-https://raw.githubusercontent.com/Nunchi-trade/agent-cli/main/skills/pulse/SKILL.md
-https://raw.githubusercontent.com/Nunchi-trade/agent-cli/main/skills/guard/SKILL.md
-https://raw.githubusercontent.com/Nunchi-trade/agent-cli/main/skills/reflect/SKILL.md
```
### Install a skill (OpenClaw / ClawHub)
@@ -212,7 +201,7 @@ cp ~/agent-cli/cli/skill.md ~/.claude/skills/yex-trader/SKILL.md
---
-## Autonomous Trading Stack
+## Active Operator Surface
### Onboard
@@ -231,240 +220,22 @@ hl hedge propose BTC --dry-run # Preview CFI v2 hedge proposal
---
-### Guard — Dynamic Stop Loss
+### CFI hedge commands
-Trailing stop system with tiered profit-locking. Protects profits while letting winners run.
-
-**Two phases:**
-- **Phase 1 (Let it breathe)** — Wide retrace tolerance while position builds. Auto-cut at 90 min if no graduation; weak-peak early cut at 45 min if peak ROE < 3%.
-- **Phase 2 (Lock the bag)** — Tiered profit floors that ratchet up as ROE grows. Exchange-level stop loss synced to Hyperliquid as crash safety net.
-
-| Preset | Phase 1 Retrace | Tiers | Stagnation TP |
-|--------|----------------|-------|---------------|
-| `moderate` | 3% | 6 tiers (10-100% ROE) | No |
-| `tight` | 5% | 4 tiers (10-75% ROE) | Yes (8% ROE, 1h) |
-
-```bash
-hl guard run -i ETH-PERP --preset tight
-```
-
-**[Download SKILL.md](skills/guard/SKILL.md)**
-
----
-
-### Radar — Opportunity Radar
-
-Multi-factor screening engine that evaluates all HL perps for trade setups. 4-stage funnel, scores 0-400.
-
-| Pillar | Weight | Signals |
-|--------|--------|---------|
-| Market Structure | 35 | Volume, OI, liquidity |
-| Technicals | 30 | RSI, EMA, patterns, hourly trend |
-| Funding | 20 | Rate extremes, direction bias |
-| BTC Macro | 15 | Trend alignment, regime filter |
-
-```bash
-hl radar once --mock # Single scan
-hl radar run --mock # Continuous (every 15 min)
-```
-
-**[Download SKILL.md](skills/radar/SKILL.md)**
-
----
-
-### Pulse — Emerging Momentum Detector
-
-Detects assets with sudden capital inflow using OI, volume, funding, and price signals. Runs every 60 seconds.
-
-**5-tier signal taxonomy** for entry classification, plus informational signals for Radar scoring:
-
-| Tier | Signal | Trigger | Confidence |
-|------|--------|---------|------------|
-| 1 | `FIRST_JUMP` | First asset in sector with OI + volume breakout | 100 |
-| 2 | `CONTRIB_EXPLOSION` | OI +15% **AND** volume 5x (simultaneous extreme) | 95 |
-| 3 | `IMMEDIATE_MOVER` | OI +15% **OR** volume 5x (either extreme) | 80 |
-| 4 | `NEW_ENTRY_DEEP` | OI grows 8%+ but volume stays low — smart money accumulation | 65 |
-| 5 | `DEEP_CLIMBER` | Sustained OI climb 5%+ per window over 3+ consecutive scans | 55 |
-| — | `VOLUME_SURGE` | 4h volume / average > 3x | 70 |
-| — | `OI_BREAKOUT` | OI jumps 8%+ above baseline | 60 |
-| — | `FUNDING_FLIP` | Funding rate reverses or accelerates 50%+ | 50 |
-
-```bash
-hl pulse once --mock # Single scan
-hl pulse run --mock # Continuous (every 60s)
-```
-
-**[Download SKILL.md](skills/pulse/SKILL.md)**
-
----
-
-### APEX — Autonomous Multi-Slot Strategy
-
-The top-level orchestrator. Composes Radar + Pulse + Guard into a single autonomous strategy managing 2-3 concurrent positions.
-
-**Tick schedule** (60s base):
-- Every tick: Fetch prices, update ROEs, check Guard, run Pulse, evaluate entry/exit
-- Every 5 ticks: Watchdog health check
-- Every 15 ticks: Run opportunity radar
-
-**Entry priority** (tier-based):
-
-| Priority | Source | Condition |
-|----------|--------|-----------|
-| 1 | FIRST_JUMP | First sector mover (tier 1) |
-| 2 | CONTRIB_EXPLOSION | Simultaneous extreme OI + volume (tier 2) |
-| 3 | Smart money | Pulse confidence > 90 |
-| 4 | IMMEDIATE_MOVER | Either extreme metric (tier 3) |
-| 5 | Radar | Score > 170 |
-| 6 | NEW_ENTRY_DEEP | Limit-order accumulation (tier 4) |
-| 7 | DEEP_CLIMBER | Sustained OI trend (tier 5) |
-
-**Presets:**
-
-| Preset | Slots | Leverage | Radar Threshold | Daily Loss Limit |
-|--------|-------|----------|-------------------|------------------|
-| `default` | 3 | 10x | 170 | $500 |
-| `conservative` | 2 | 5x | 190 | $250 |
-| `aggressive` | 3 | 15x | 150 | $1,000 |
-
-```bash
-hl apex run --mock --max-ticks 10 # Mock test
-hl apex run # Live testnet
-hl apex run --preset conservative --mainnet # Live mainnet
-```
-
-**[Download SKILL.md](skills/apex/SKILL.md)**
-
----
-
-### REFLECT — Performance Review
-
-Nightly self-improvement loop. Reads trade history, computes metrics, detects patterns, generates actionable recommendations.
-
-| Metric | Description |
-|--------|-------------|
-| Win Rate | % of round trips with positive net PnL |
-| FDR | Fee Drag Ratio — fees as % of gross wins |
-| Direction Split | Long vs short win rates and PnL |
-| Holding Periods | Bucketed by <5m, 5-15m, 15-60m, 1-4h, 4h+ |
-| Monster Dependency | % of net PnL from best single trade |
-
-```bash
-hl reflect run --since 2026-03-01
-hl reflect report
-hl reflect history -n 10
-```
-
-**[Download SKILL.md](skills/reflect/SKILL.md)**
-
-### REFLECT Self-Improvement Loop
-
-When running inside APEX, REFLECT executes automatically every 240 ticks (~4 hours) and at a configurable UTC hour (default 04:00). It reads the trade log, computes performance metrics, and **auto-adjusts APEX parameters** based on findings:
-
-| Finding | Automatic Adjustment |
-|---------|---------------------|
-| FDR > 30% (fees eating profits) | Raise radar threshold, disable immediate mover entries |
-| Win rate < 40% | Tighten both radar and movers confidence thresholds |
-| 5+ consecutive losses | Reduce daily loss limit by 20% |
-| Direction imbalance (e.g. longs losing) | Limit same-direction slots |
-| Fees exceed gross PnL | **Emergency mode**: disable auto-entries, raise all thresholds |
-| Profitable + healthy | Slightly relax thresholds toward defaults |
-
-All adjustments have guardrail bounds — parameters can't swing wildly. Disable with `reflect_auto_adjust: false` in APEX config.
-
-**Scheduled tasks** (built into APEX tick loop):
-- **Daily PnL reset** at UTC midnight — clears daily loss tracking
-- **REFLECT comprehensive report** at UTC 04:00 — full performance review with markdown report saved to `data/apex/reflect/`
-
----
-
-### Production Safety
-
-Built-in safety systems that protect positions even when the runner process crashes.
-
-#### Exchange-Level Stop Loss Sync
-
-Guard places a **trigger order directly on Hyperliquid** as a safety net. If the runner crashes, the exchange-side stop loss remains active. Synced on entry, tier ratchet, and startup — intentionally left in place on shutdown.
-
-```
-Position Entry → Place SL trigger order at Phase 1 floor
-Tier Ratchet → Cancel old SL, place new at higher tier floor
-Position Close → Cancel SL trigger order
-Runner Crash → Exchange SL stays active (that's the point)
-```
-
-#### Clearinghouse Reconciliation
-
-Bidirectional reconciliation between APEX slots and Hyperliquid positions. Detects orphaned exchange positions, orphaned slots, and size mismatches. Runs on startup and periodically via watchdog.
-
-```bash
-hl apex reconcile # Check for discrepancies
-hl apex reconcile --fix # Auto-adopt orphans, fix sizes
-```
-
-| Discrepancy | Severity | Auto-Fix |
-|-------------|----------|----------|
-| Orphan exchange position | Critical | Adopt into empty slot + create Guard |
-| Orphan slot (no position) | Warning | Mark slot closed |
-| Size mismatch >10% | Critical | Update slot to match exchange |
-
-#### Risk Guardian
-
-Graduated risk response with three states and automatic transitions:
-
-```
-OPEN ──(2 consecutive losses)──→ COOLDOWN ──(trigger again)──→ CLOSED
- ↑ │ │
- └──────(auto-expiry 30 min)────────┘ │
- └────────────────────(daily reset)──────────────────────────────┘
-```
-
-| State | Entries | Exits | Trigger |
-|-------|---------|-------|---------|
-| `OPEN` | Allowed | Allowed | Default |
-| `COOLDOWN` | **Blocked** | Allowed | 2+ consecutive losses or drawdown >= 50% of limit |
-| `CLOSED` | **Blocked** | **Blocked** | Daily loss limit hit |
-
-Exchange-level stop losses remain active in all states.
-
-#### Rotation Cooldown
-
-Anti-churn protection:
-- **Minimum hold (45 min)** — Conviction collapse and stagnation exits blocked until 45 min. Guard hard stops and daily loss still override.
-- **Slot cooldown (5 min)** — Closed slots can't be reused for 5 minutes.
-
-#### State Archiving
-
-Closed position state files archived to `data/archive/{YYYY-MM-DD}/` on close. Trade audit trail (`trades.jsonl`) is never archived.
+The active trading path is CFI v2 funding-rate hedging. Use `hl hedge ...` for proposals, execution, status, automation, and backtests, or `hl run cfi_hedge ...` to run the same logic through the standard strategy loop.
```bash
-hl apex archive # Archive all closed state files
-hl apex archive --days 7 # Only older than 7 days
-hl apex archive --dry-run # Preview without moving
-```
-
-#### ALO Fee Optimization
-
-Entry orders default to **ALO (post-only)** for maker rebates (~3 bps savings per round-trip). Falls back to GTC if ALO is rejected. Exits and Guard closes always use IOC.
-
----
-
-### Autoresearch-Powered REFLECT
-
-Connects REFLECT to an autonomous optimization loop. A backtest harness replays historical trades against config variants, and an iterative agent loop finds parameter improvements.
-
-```bash
-python3 scripts/backtest_apex.py --config apex_config.json --trades data/cli/trades.jsonl
+hl hedge propose BTC --dry-run
+hl hedge execute BTC --dry-run
+hl hedge status --coin BTC --watch
+hl hedge auto --coins BTC --dry-run
+hl hedge backtest --coin BTC --days 30
+hl run cfi_hedge -i BTCSWP-PARA --mock --max-ticks 5
```
-REFLECT auto-generates research directions:
+### Archived legacy stack
-| Finding | Suggested Direction |
-|---------|-------------------|
-| FDR > 30% | Raise `radar_score_threshold` in [170, 250] |
-| Win rate < 40% | Sweep `pulse_confidence_threshold` in [70, 95] |
-| Direction imbalance | Set `max_same_direction` to 1 |
-| Healthy + profitable | Try lowering `radar_score_threshold` in [140, 170] |
+APEX, Radar, Pulse, Guard, Reflect, the quoting engine, SEDA oracle, and Hermes/OpenClaw deploy templates are archived under `_archive/`. Their historical docs, commands, modules, skills, scripts, and tests remain there for reference, but those commands are not registered by `cli/main.py` and their tools are not exposed by the active MCP server.
---
@@ -480,15 +251,6 @@ hl account # Show HL account state
hl strategies # List all strategies
hl skills list # Discover installed skills
-# Autonomous stack
-hl apex run [options] # APEX multi-slot orchestrator
-hl apex reconcile [--fix] # Reconcile state vs exchange
-hl apex archive [--days N] # Archive closed state files
-hl radar run [options] # Opportunity radar
-hl pulse run [options] # Pulse momentum detector
-hl guard run -i ETH-PERP [options] # Guard trailing stop
-hl reflect run [--since DATE] # Performance review
-
# Infrastructure
hl builder approve [--mainnet] # Approve builder fee
hl wallet auto [--save-env] # Create wallet (agent-friendly)
@@ -509,7 +271,9 @@ hl mcp serve # stdio transport (default)
hl mcp serve --transport sse # SSE transport
```
-**24 MCP tools** for account state, trading, CFI funding hedges, APEX/Radar/REFLECT, wallet/setup, safety actions (`schedule_cancel`, `emergency_close_all`), and agent memory/journal helpers. Run `hl mcp serve` to expose them to any MCP host.
+**20 MCP tools** for account state, trading, CFI funding hedges, wallet/setup, safety actions (`schedule_cancel`, `emergency_close_all`), order/funding reads, and agent memory/journal helpers. Run `hl mcp serve` to expose them to any MCP host.
+
+Active tools: `strategies`, `builder_status`, `wallet_list`, `wallet_auto`, `setup_check`, `account`, `status`, `trade`, `run_strategy`, `schedule_cancel`, `emergency_close_all`, `order_status`, `funding_rates`, `funding_hedge_propose`, `funding_hedge_backtest`, `funding_hedge_execute`, `agent_memory`, `trade_journal`, `judge_report`, `obsidian_context`.
Fast tools (strategies, builder, wallet, setup, memory, journal, judge) call Python directly — zero subprocess overhead.
@@ -526,7 +290,7 @@ mcp_servers:
# cwd: /path/to/agent-cli # if not launched from the repo root
```
-This is exactly what the legacy `archive/deploy/hermes-railway` template auto-generates on boot (alongside `platform_toolsets`), so a deployed Hermes agent is wired out of the box — no OpenClaw-specific assumptions anywhere in the MCP server.
+The archived Hermes template under `_archive/deploy/hermes-railway` generated this shape for legacy experiments, but the active server is harness-neutral and does not expose the archived APEX/Radar/Pulse/Guard/Reflect toolset.
### HTTP API & SSE
@@ -551,14 +315,14 @@ defaults to `RUN_MODE=mcp`; Nunchi operates this runner pool behind
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `HL_TESTNET` | No | `true` | `true` for testnet, `false` for mainnet |
-| `RUN_MODE` | No | `mcp` | `mcp` for the hosted tools runtime; `apex`/`strategy` are local or legacy operator modes |
+| `RUN_MODE` | No | `mcp` | `mcp` for the hosted tools runtime; `strategy` for local `cfi_hedge` loops. Legacy `apex` falls back to `strategy`. |
| `DATA_DIR` | No | `/data` | Persistent ledgers, wallet state, and metering data |
| `NUNCHI_METERING_URL` | No | — | Generic web-auth metering upload endpoint when the runner reports usage |
| `NUNCHI_METERING_TOKEN` | No | — | Metering bearer token issued by web-auth/gateway config |
**Run modes:**
- **mcp** (default) — SSE MCP server for the shared Railway tools runtime.
-- **apex** / **strategy** — direct autonomous loops for local/self-hosted operators, not the Nunchi subscription product path.
+- **strategy** — local/self-hosted `cfi_hedge` loop, not the Nunchi subscription product path. Legacy `apex`/`wolf` values are deprecated and fall back to `strategy`.
### Legacy Agent Templates
@@ -567,8 +331,8 @@ self-host templates. They are not part of the new hosted MCP subscription
architecture because they provision user-facing conversational/autonomous
agents. Do not expose them as the paid Nunchi product path.
-For legacy experiments, use `archive/deploy/openclaw-railway/railway.toml` or
-`archive/deploy/hermes-railway/railway.toml` as the config-as-code path and keep the
+For legacy experiments, use `_archive/deploy/openclaw-railway/railway.toml` or
+`_archive/deploy/hermes-railway/railway.toml` as the config-as-code path and keep the
Railway build root at the repo root.
---
@@ -577,28 +341,17 @@ Railway build root at the repo root.
```
cli/ CLI commands and trading engine
- commands/ Subcommand modules (run, apex, radar, pulse, guard, reflect, house, ...)
- mcp_server.py MCP server (24 tools via FastMCP)
+ commands/ Active subcommands (run, hedge, wallet, setup, mcp, skills, journal, keys, margin, trading, house, policy, ...)
+ mcp_server.py MCP server (20 tools via FastMCP)
hl_adapter.py Direct HL API adapter (live + mock)
builder_fee.py Builder fee config (HL native BuilderInfo)
keystore.py Encrypted keystore (geth-compatible)
strategy_registry.py Strategy + HIP-3 market definitions (YEX, OSRS, PARA)
strategies/ cfi_hedge + archived legacy strategies (_archive/)
-modules/ Pure logic modules (zero I/O)
- apex_engine.py APEX decision engine
- radar_engine.py Opportunity radar
- pulse_engine.py Pulse momentum detector (5-tier signal taxonomy)
- trailing_stop.py Guard trailing stop (Phase 1 auto-cut)
- reflect_engine.py Performance analysis
- reconciliation.py Clearinghouse reconciliation engine
- archiver.py State file archiving
+modules/ Active shared logic modules; archived APEX/Radar/Pulse/Guard/Reflect modules live under _archive/modules/
skills/ Agent Skills (SKILL.md + runners)
onboard/ First-time setup guide
- apex/ APEX orchestrator
- radar/ Opportunity radar
- pulse/ Pulse momentum detector
- guard/ Dynamic stop loss
- reflect/ Performance review
+_archive/ Legacy operator stack, skills, deploy templates, scripts, docs, and tests
sdk/ Strategy base class and model registry
parent/ HL API proxy, position tracking, risk management
scripts/ Backtest harness, bootstrap