# ── IGUANA (v2 supervised) ───────────────────────────────────────────
# XYZ macro index trend — the simplest possible XYZ equity exposure.
# SINGLE wallet, SINGLE recipe, ONE supervised scanner.
#
# Ported from senpi-skills/iguana (producer v1.0.1, config v1.0.0) to the v2
# supervised external-scanner contract. The producer daemon is gone: the runtime
# supervises ./scanners/scan.py and calls scan(inputs, ctx) every
# `interval_seconds` (300s). All gates + scoring preserved exactly; the pure
# trend/scoring functions are ported VERBATIM (they were already unit-tested in
# the source). See scan.py + scoring.py.
name: iguana-tracker
version: 2.0.0
group: iguana                       # agent-facing handle (harmless for single-wallet)
description: >
  IGUANA — XYZ Macro Index Trend. "I want stock-market exposure on Hyperliquid
  without picking stocks." Trend-follows the two broad XYZ indices xyz:SP500 +
  xyz:XYZ100 — two assets, ONE decision per tick. Each tick computes a 4-day
  trend strength (% change of the latest 4h close vs 24 bars ago) per index,
  picks the stronger move past minTrendPct (1.5%), scores it (base 3, +2 if the
  move is strong >= 4%, +1 if volume is rising), and emits the SINGLE strongest
  index trend in its direction if score >= minScore (4). Conservative sizing
  (20% margin, 3x). DSL: 48h hard_timeout (XYZ weekend pricing-gap risk),
  weak_peak 8h@3, 5-tier phase2 ladder. ONBOARDING TIER.

strategy:
  wallet: "${IGUANA_WALLET}"
  slots: 1                          # source slots 1 (iguana emits <=1 signal/tick — two assets, one decision)
  margin_pct: 20                    # source margin_pct 20 (% of account per slot; scan.py carries the exact marginPct)
  default_leverage: 3               # source leverage 3 (capped at MAX_LEVERAGE 5 in scan.py)
  trading_risk: conservative        # source trading_risk conservative
  enabled: true

scanners:
  - name: position_tracker          # built-in: feeds DSL exit engine
    type: position_tracker
    interval_seconds: 10            # source position_tracker interval 10s

  - name: iguana_signals            # supervised external scanner
    type: external_scanner
    path: ./scanners
    entrypoint: scan.py
    interval_seconds: 300           # source producer_daemon interval_seconds 300 (5min)
    timeout_seconds: 180            # source tick_timeout 180
    default_signal_validity_seconds: 600   # 2x tick; pass-through gate re-scores next tick
    state_history_max_count: 200    # holds the per-coin 240s recent-signal dedup map records
    inputs:
      # ── universe + trend gates (config v1.0.0) ──
      whitelist: ["xyz:SP500", "xyz:XYZ100"]   # the two broad XYZ indices
      trendLookbackBars: 24         # 24 × 4h bars = 4 days
      minTrendPct: 1.5              # minimum |4-day move| to call it a trend
      strongTrendPct: 4.0           # |move| >= this scores the strong-trend bonus (+2)
      minScore: 4                   # additive-score floor to emit
      # ── sizing (config v1.0.0) ──
      marginPct: 0.20               # margin = account_value * 0.20
      leverage: 3                   # leverage (capped at 5 in scan.py)
    signal_data_schema:
      score: { type: number }
      direction: { type: string }
      reasons: { type: array, required: false }
      trendPct: { type: number, required: false }
      volumeTrendPct: { type: number, required: false }
      heldAssets: { type: array, required: false }

actions:
  - name: position_tracker_action   # rule-based lifecycle → DSL
    action_type: POSITION_TRACKER
    decision_mode: rule
    scanners: [position_tracker]

  - name: iguana_entry              # OPEN_POSITION, rule mode (source LLM gate was pure pass-through)
    action_type: OPEN_POSITION
    decision_mode: rule
    scanners: [iguana_signals]
    params:
      order_type: FEE_OPTIMIZED_LIMIT
      fee_optimized_limit_options:
        ensure_execution_as_taker: true    # source entry ensureExecutionAsTaker true — ride the trend NOW
        execution_timeout_seconds: 30
    context:
      - type: signal
        scanner: iguana_signals

# ── EXIT (DSL — balanced, XYZ-tuned; preset preserved from source v1.0.0) ──
#
# Index trends extend over days/weeks; the 48h hard_timeout accommodates the
# weekend pricing-gap risk on XYZ. weak_peak_cut bails from flat-but-tired
# positions before the weekend gap. dead_weight_cut is disabled (source).
exit:
  engine: dsl
  interval_seconds: 60              # source exit interval_seconds 60
  order_type: FEE_OPTIMIZED_LIMIT
  fee_optimized_limit_options:
    ensure_execution_as_taker: true
    execution_timeout_seconds: 30
  dsl_preset:
    hard_timeout:
      enabled: true
      interval_in_minutes: 2880     # source hard_timeout 2880min (48h — XYZ weekend pricing-gap risk)
    weak_peak_cut:
      enabled: true
      interval_in_minutes: 480      # source weak_peak 480min (8h)
      min_value: 3.0                # source weak_peak min 3.0%
    dead_weight_cut:
      enabled: false                # source disabled
      interval_in_minutes: 60       # inert (enabled:false) — placeholder for the parser
    phase1:
      enabled: true
      max_loss_pct: 12.0            # source phase1 max_loss 12
      retrace_threshold: 8          # source phase1 retrace 8
      consecutive_breaches_required: 1
    phase2:
      enabled: true
      tiers:                        # source T0..T4 — carried verbatim
        - { trigger_pct: 5,  lock_hw_pct: 0 }
        - { trigger_pct: 10, lock_hw_pct: 40 }
        - { trigger_pct: 18, lock_hw_pct: 60 }
        - { trigger_pct: 30, lock_hw_pct: 75 }
        - { trigger_pct: 50, lock_hw_pct: 85 }

# ── RISK guard rails (from source runtime.yaml; minutes/hours → seconds) ──
risk:
  data_retention_seconds: 345600    # 96h (was data_retention_hours 96)
  guard_rails:
    daily_loss_limit_pct: 12
    max_entries_per_day: 2
    bypass_max_entries_per_day_on_profit: false
    max_consecutive_losses: 3
    cooldown_seconds: 5400          # was cooldown_minutes 90
    drawdown_halt_pct: 20
    drawdown_reset_on_day_rollover: false
    per_asset_cooldown_seconds: 21600   # was per_asset_cooldown_minutes 360 (6h)

notifications:
  telegram_chat_id: "${TELEGRAM_CHAT_ID}"
  dsl_lifecycle: true
  dsl_notify_sl_updates: false
  action_lifecycle: true
