Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
303 changes: 29 additions & 274 deletions README.md

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions _archive/README.md
Original file line number Diff line number Diff line change
@@ -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
```
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion cli/api/status_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
16 changes: 8 additions & 8 deletions cli/commands/hedge.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
"""
Expand Down Expand Up @@ -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,
)

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
)

Expand All @@ -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"))
Expand Down
16 changes: 0 additions & 16 deletions cli/commands/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
120 changes: 1 addition & 119 deletions cli/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion cli/hedge_display.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand Down
10 changes: 0 additions & 10 deletions cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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")
Expand Down
Loading