Skip to content

Conversation

@fzheng
Copy link
Owner

@fzheng fzheng commented Dec 15, 2025

No description provided.

fzheng and others added 15 commits December 13, 2025 13:54
Phase 4 - Risk Management:
- Kelly criterion position sizing (fractional Kelly, 25% default)
- Real execution wrapper using hyperliquid-python-sdk
- Stop-loss manager with trailing stops and timeouts
- Circuit breakers (max positions, API error pause, loss streak pause)
- Database migrations for Kelly config, exchange config, active stops

Phase 5 - Market Regime Detection:
- Regime classifier (TRENDING, RANGING, VOLATILE, UNKNOWN)
- MA20/MA50 spread for trend detection
- ATR-based volatility ratio
- Regime-specific parameter presets for stops and Kelly sizing
- Dashboard regime display endpoints

Code cleanup:
- Remove deprecated process_fill_for_consensus function
- Update phase references in code comments
- Delete outdated docs (phase-3e, phase-3f, dashboard-redesign)
- Update DEVELOPMENT_PLAN.md with completed Phase 4/5 status
- Update API.md with regime detection endpoints
- Update RUNBOOK.md with Kelly and regime operations

Tests: 348 Python + 1,035 TypeScript = 1,383 passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Integrate regime detection, risk governor, and execution:
- Regime adjustments now influence ATR stops in main.py
- Regime adjustments now influence Kelly sizing in executor.py
- Risk governor validation added to executor before trades
- Real execution path through hl_exchange (disabled by default)
- Add 12 integration tests for regime/risk/executor wiring
- Update DEVELOPMENT_PLAN.md to reflect integration status

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Address peer review findings:
- Fix risk governor call (use check_risk_before_trade instead of missing alias)
- Add daily PnL tracking via risk_daily_pnl table for drawdown kill switch
- Add regime-aware confidence gating to check_risk_limits()
- Add circuit breaker check before real execution path
- Add 8 new integration tests for daily PnL, regime confidence, circuit breakers

All 368 Python tests and 1,035 TypeScript tests pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
…itions

Address additional peer review findings:
- Re-run risk governor AFTER Kelly/fixed sizing with actual proposed_size_usd
- Circuit breaker now derives position counts from account state per-symbol
- Circuit breaker check moved to validate_execution (applies to both real/sim)
- Remove redundant circuit breaker check from real execution branch
- Add 6 new tests for proposed size, position tracking, migration verification

All 374 Python tests and 1,035 TypeScript tests pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Clean up API and address review feedback:
- Add update_positions_from_account_state() public method
- Add get_symbol_position_count() accessor
- Change run_circuit_breaker_checks to use symbol_position_count param
- Remove redundant zero-size risk governor call (now just kill switch check)
- Document that daily PnL is equity-based (includes unrealized)
- Add test for new symbol position allowed scenario

All 375 Python tests and 1,035 TypeScript tests pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add is_kill_switch_active() for lightweight early bailout check
- Reuse cached account_state from context instead of double API fetch
- Add 2 tests for is_kill_switch_active behavior

All 377 Python tests and 1,035 TypeScript tests pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add retry with exponential backoff for account state fetch (3 retries, 500ms base)
- Add decide_safety_block_total Prometheus counter with guard labels:
  - kill_switch: Daily drawdown triggered
  - account_state: API unavailable after retries
  - risk_governor: Liquidation/exposure limits
  - circuit_breaker: Position/API/loss limits
- Block execution on any safety check failure (fail-closed posture)
- Add 7 new integration tests for fail-closed behavior
- Update docs with safety hardening section
- Update README status to Phase 4-5 Complete

Test counts: 384 Python + 1,035 TypeScript tests passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Implements abstract exchange interface with adapters for:
- Hyperliquid (DEX, wraps hyperliquid-python-sdk)
- Aster DEX (ECDSA/EIP-712 signing, agent wallet support)
- Bybit (CEX, pybit SDK for USDT linear perpetuals)

Key components:
- ExchangeInterface ABC with unified operations
- ExchangeConfig for secure credential loading from env vars
- Factory functions: get_exchange(), create_exchange(), connect_exchange()
- Data classes: OrderParams, OrderResult, Position, Balance, MarketData

34 unit tests covering interface, factory, and all adapters.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Update DEVELOPMENT_PLAN.md with Phase 6 status and architecture diagram
- Add multi-exchange module to API.md with usage examples
- Update test counts to 418 Python tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
This commit completes Phase 6 multi-exchange integration by wiring the
exchange adapters into the execution path:

ExchangeManager (exchanges/manager.py):
- Routes execution to appropriate adapter based on config
- Aggregates balance/positions across connected exchanges
- Manages connection lifecycle for multiple exchanges
- Auto-detects configured exchanges from environment

Executor updates:
- Uses ExchangeManager when exchange is connected
- Falls back to legacy hl_exchange for backward compatibility
- Logs which exchange was used for each trade
- Calculates stop/take-profit prices for adapters

Risk Governor updates:
- Tracks positions per exchange
- Aggregates risk state across all exchanges
- AggregatedRiskState dataclass for portfolio view
- Per-exchange position count queries

Database migration (031_multi_exchange.sql):
- Adds default_exchange to execution_config
- Adds exchange_type to execution_logs
- Adds exchange to active_stops
- Creates exchange_connections table
- Creates exchange_balances table for portfolio tracking

Tests:
- 27 new tests for ExchangeManager (61 total in test_exchanges.py)
- Tests for singleton, mocked adapters, aggregation
- All 445 hl-decide tests passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Phase 6.1 Multi-Exchange Refinements - All gaps resolved:

## Gap 1: Slippage Sizing ✅
- Two-stage slippage: reference $10k at consensus, Kelly-sized at executor
- EV re-validation rejects signals if actual slippage pushes below minimum
- 6 new tests for slippage recalculation

## Gap 2: Dynamic Hold-Time ✅
- HoldTimeEstimator computes median from position_signals.hold_secs
- Per-asset estimates with regime-adjusted multipliers
- 5-minute cache with fallback to 24h default
- 26 new tests for hold time estimation

## Gap 3: Multi-Exchange Regime Detection ✅
- RegimeDetector accepts exchange parameter for venue-specific detection
- _fetch_candles_multi_exchange routes through ATR provider infrastructure
- Exchange-specific cache keys for separate per-venue caching
- RegimeAnalysis includes exchange field for audit trail
- 10 new tests (49 total regime tests)

## Gap 4: Per-Venue EV Calculation ✅
- ConsensusDetector.calculate_ev_for_exchange() for specific exchange
- ConsensusDetector.compare_ev_across_exchanges() for venue comparison
- Returns detailed cost breakdown (fees, slippage, funding, hold_hours)
- Identifies best execution venue by net EV
- 17 new tests for per-venue EV

## Gap 5: Normalization in All Risk Paths ✅
- ExchangeManager.get_aggregated_balance() now uses USD normalization
- Lazy import to avoid circular dependency
- AggregatedBalance documented as USD-normalized

New Files:
- app/hold_time_estimator.py
- app/account_normalizer.py
- app/fee_provider.py
- app/funding_provider.py
- app/slippage_provider.py
- app/atr_provider/ (interface, manager, hyperliquid, bybit)
- tests/test_hold_time_estimator.py
- tests/test_ev_per_venue.py
- tests/test_account_normalizer.py
- tests/test_atr_provider.py
- tests/test_fee_provider.py
- tests/test_funding_provider.py
- tests/test_slippage_provider.py

Test Results: 703 Python tests passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Place SL/TP orders directly on exchanges instead of local polling:
- Add set_stop_loss_take_profit() combined method to interface
- Add cancel_stop_orders() to all adapters (HL, Bybit, Aster)
- Add supports_native_stops property for capability detection
- StopManager auto-selects native vs polling based on config
- Polling fallback for trailing stops or when native fails
- 28 new tests for native stop functionality

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Wire compare_ev_across_exchanges() into consensus gate to compare EV
  across multiple venues (hyperliquid, bybit) and select best by net EV
- Add target_exchange, fees_bps, slippage_bps, funding_bps fields to
  ConsensusSignal dataclass for venue routing and cost breakdown tracking
- Add target_exchange parameter to executor.maybe_execute_signal() for
  per-signal venue routing
- Add migration 033_consensus_signal_venue.sql for schema updates
- Add 9 new tests for Phase 6.3 (26 total in test_ev_per_venue.py)
- Update DEVELOPMENT_PLAN.md with Phase 6.3 documentation

Closes highest-risk gap from quant review: "EV target exchange is still
global" - consensus now calculates venue-specific EV and routes signals
to the exchange with highest net expected value.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Phase 6.5 - Per-Signal Venue Selection:
- Add PER_SIGNAL_VENUE_SELECTION config (default: true)
- Add VENUE_SELECTION_EXCHANGES config (default: hyperliquid,bybit)
- Each consensus signal now compares EV across exchanges
- Select best execution venue by highest net EV
- Signal carries target_exchange, fees_bps, slippage_bps, funding_bps
- Executor routes to signal's selected venue
- 18 new tests in test_phase_6_5.py

Phase 6.4 - Per-Venue Data-Quality Fallbacks:
- Non-HL venues use ρ=0.5 default correlation (conservative)
- 0.85x hold-time multiplier for non-HL exchanges
- Per-exchange rate limit delays (HL 300ms, Bybit 750ms)
- 21 new tests in test_phase_6_4.py

USDT=USD Simplification:
- Remove CoinGecko API integration for USDT/USD conversion
- Treat USDT as 1:1 with USD (no API calls needed)
- Simplify AccountNormalizer (no caching, no depeg warnings)
- Update executor to remove is_depeg_warning from metadata
- Simplify tests from 51 to 20 (removed API mock tests)
- Update all documentation to reflect simplified approach

Test Results:
- 1,035 TypeScript tests passing
- 765 Python tests passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Change `from app.exchanges.interface` to `from .exchanges.interface`
to fix ModuleNotFoundError in Docker container.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@fzheng fzheng merged commit 40c1499 into main Dec 15, 2025
5 checks passed
@fzheng fzheng deleted the phase-4 branch December 15, 2025 04:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants