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 @@ Strategy Tests License - MCP + MCP

@@ -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