S
strat-decoder
hyperliquid · reverse-engineer
Completed 38 minutes ago

Swing Trader

0xdc83cb546ab87ced1d2c53caa4606b4cf7e20a8e

← New
Window
30.0d
Fills
325
Closed PnL
$2.48K
Win rate
67.7%

TL;DR

Long-only multi-day swing trader running a basket of crypto alt-perps and tokenized US equities, executed as aggressive sub-second taker sweeps. The signature is a 67.7% win rate paired with avg_winner ($58) smaller than avg_loser ($73) and no hard stop — winners are scaled out in hours, losers are flushed in one block near day 5. Net +$2,479 over 30 days against a -$2,190 peak drawdown, so roughly 88% of ending PnL was once at risk.

How they trade

The book spans eight names split between high-beta alt perps (CHIP, ENA, XPL, SYRUP, ZRO) and tokenized equities (MSFT, MU, HIMS), with MSFT alone accounting for 40% of the $627k notional volume. Every observed fill is Open Long or Close Long; no shorts. Entries fire as bursts of 10+ child taker fills inside a single second, walking the book 5–15 bps — maker share is only 14.2%. Activity clusters at 15:00 UTC (119 of 325 fills, 37%), with secondary spikes at 13:00 and 06:00, and the bulk of volume on Tuesday–Wednesday, consistent with trading the US cash open on tokenized equities. Sizing is tiered: ~$4.5–5k average notional on equity perps versus ~$1.4k on alt perps, and there is no pyramiding inside a position — one entry burst, then a laddered scale-out across 5–15 ticks. Winners typically close within 2–6 hours; losers are held through multi-hour drawdowns and then dumped as a single capitulation print, with p95 hold at ~4.9 days and max at ~5.74 days acting as a soft time-stop.

Edge hypothesis

The edge looks like short-horizon directional reads on illiquid alt perps (CHIP, ENA, XPL all 100% win-rate, all longs), captured via fast taker execution before the move extends. The 15:00 UTC concentration on equity perps suggests an attempt to ride the US open's predictable opening volatility, but that sleeve actively bleeds (MSFT 41% win, HIMS 0%). Net edge is the alt-coin sleeve subsidizing a losing equity-open habit.

Numbers that matter

Metric Value
Win rate / profit factor 67.7% / 1.68
Avg winner vs avg loser $58.41 vs -$73.08
Median / p95 hold 15.7h / 4.9d
Maker pct 14.2%
Max drawdown vs ending PnL -$2,190 vs +$2,479
15:00 UTC fill share 119 / 325 (37%)
MSFT volume share / PnL 40% / -$975
Funding vs trading PnL -$133 vs +$2,479

What we cannot conclude

Swing Trader conf 0.55 also: Scalper
  • median hold ~15.7h, avg hold ~36.7h (hours-to-days)
  • 22.7 fills/day across 8 assets, moderate cadence
  • win_rate 67.7% with avg_winner $58 < |avg_loser| $73 (asymmetric losers)
  • profit_factor 1.68, expectancy +$16
  • maker_pct only 14% — taker-driven, not MM
  • funding -$133 vs trading PnL +$2479 — not funding farming
  • max drawdown -$2190 vs ending +$2479 — volatile equity curve
  • top asset MSFT (40% vol) lost -$975 while CHIP/ENA carried PnL

Entry rules

  • Long-only directional entries via aggressive taker sweeps

    Always side=Buy to Open Long; entries executed as a burst of ≥10 child fills inside ≤1 second walking the book up 5-15 bps (taker). No shorts observed.

    Evidence: CHIP 2026-04-22T06:28:54Z: 12 buy child-fills in <1s from 0.082864→0.083000 (~16 bps slippage); MSFT 2026-04-22T12:29:04Z: 13 child buys in same second 427.79→428.16. maker_pct=14.2% on entries (taker-driven).

  • Re-enter immediately after a profitable scale-out

    After fully closing a winner, re-open same asset same direction within minutes if price continues higher (momentum continuation add).

    Evidence: CHIP closed at 0.10458 12:27:26 for +$1214 winner, then re-opened long at 0.1119-0.1122 at 15:01:19 (~7% higher). MSFT closed 429.81 at 15:01:03, re-opened 431.42 at 15:09:22.

  • Concentrated session timing

    Open new positions clustered around 06:00, 13:00 and especially 15:00 UTC (US pre-open / cash open) on Tue-Wed.

    Evidence: fills_by_hour: 15:00 UTC = 119 fills (37% of all), 13:00 = 38, 06:00 = 33; Wed = 134 fills, Tue = 92; quietest hour 04:00 UTC.

  • Multi-asset basket bet, sized larger on equity-perps

    When entering, fire a basket: average MSFT/MU/HIMS notional ~$4.5-5k per fill vs ~$1.4k for alt-perps; total avg fill $1931, median $630 (right-skewed).

    Evidence: xyz:MSFT 65 fills / $251k = $3.86k avg; xyz:HIMS 11 fills / $49.6k = $4.51k avg; CHIP 73 fills / $100k = $1.38k avg.

Exit rules

  • Quick profit-take within hours when in the money

    Close longs as a single-second taker sweep once unrealized PnL is positive; median hold ~15.7h, but winners often exit in 2-6h.

    Evidence: CHIP entered 06:28:54, partial close 06:30:39 (+$16 in 2 min) then full close 12:27:26 (+$2.7k 6h later). MSFT entered 12:29:04, closed 15:01:03 (+$178 in 2.5h).

  • Capitulation flush on adverse moves (no hard stop)

    When trade goes against him, holds for many hours/days then dumps the whole position in one block at market — producing the asymmetric losers (avg_loser $73 > avg_winner $58).

    Evidence: HIMS -$662 + -$372 closed in same instant 2026-04-22T06:28:46 (single capitulation). MSFT -$564/-$148/-$141/-$122 all dumped at 2026-04-27T13:45:02. SYRUP three losses (-$264,-$167,-$140) all at 2026-04-21T08:51:35.

  • Scale-out laddered through book on exit

    Exits are split into 5-15 child fills at adjacent price ticks within a few seconds (VWAP-style sweep), not a single market order.

    Evidence: CHIP 12:27:26: 10 close-long child fills 0.10456-0.10471 totaling 132k coins. MSFT 15:01:03: 11 close child-fills clustered at 429.81.

  • Hard time-stop ~5 days

    Maximum hold ≈ 5.7 days (p95 = 4.9d, max = 5.74d). Losers that aren't recovered are flushed by day 5.

    Evidence: p95_hold_seconds=424,188 (~4.9d), max=495,865s (~5.74d). MSFT entered 04-22 dumped 04-27 = ~5 days.

Sizing

Notional per leg ~$1.4k-5k (median fill $630, avg $1931). Total volume $627k over 30d ≈ implied account ~$3-10k with periodic 5-10x leverage on equity perps (HIMS single close was 427 shares × $30 ≈ $13k notional). Roughly equal-weighted across the alt basket, but ~3× heavier on tokenized stocks. No pyramiding observed within a single position — one entry burst then scale-out.

Edges

  • Fast taker execution into nascent intraday momentum on low-float alt perps (CHIP, ENA, XPL all 100% win-rate, all longs).
  • Discipline to scale out into strength: largest single winner ($1215 CHIP) was a 56k-coin slice of a 132k exit at the local top tick 0.10458 before price fell to 0.11321 close → 0.11082 loss.
  • Trading the 15:00 UTC US-cash-open window when tokenized equities have predictable opening volatility.
  • Win-rate 67.7% with profit_factor 1.68 suggests genuine short-term directional read on alt perps, partly given back by stubborn longs on lagging equities (MSFT win_rate 41%, HIMS 0%).

Risk Management

  • No hard stop-loss: largest losses (-$662 HIMS, -$564 MSFT) realized as single capitulation prints after multi-hour drawdown to peak DD -$2190 on 04-22.
  • Diversification across 8 assets / HHI 0.22 cushions single-name blowups; CHIP+ENA gains (+$4.9k) offset MSFT+HIMS+SYRUP losses (-$3.2k).
  • Implicit time-stop near 5 days flushes stale losers (MSFT closed 04-27 exactly).
  • Funding cost monitored loosely: -$133 over 222 payments (-$0.60 avg) — small relative to PnL because holds are short.
  • No shorts → fully exposed to broad market drawdowns; equity curve volatile (DD/end ratio = 88%).

Caveats

  • Only 30 days / 325 fills / 14 distinct round-trip holds — small sample, profit_factor 1.68 may not be stable.
  • No short fills observed; cannot confirm whether strategy is long-only by design or just by sample window.
  • Cannot see signals/indicators used to time entries (price action, news, on-chain) — only execution footprint.
  • Account snapshot is $0 with no open positions, so cannot infer current leverage or true equity base; sizing inferred from notional only.
  • Funding rate $-133 with 222 payments implies positions held across many funding windows but doesn't decompose by asset.
  • Cannot distinguish discretionary vs algo execution, though 1-second multi-child taker sweeps are consistent with a manual click-to-fill or a simple sweep-to-fill algo.
SwingBasketStrategy · CHIP/USDC:USDC ENA/USDC:USDC XPL/USDC:USDC · 15m
37 minutes ago
View Python source (5159 bytes)
import numpy as np
import pandas as pd
from freqtrade.strategy import IStrategy, IntParameter, DecimalParameter


class SwingBasketStrategy(IStrategy):
    """
    Distilled swing-trader strategy for wallet 0xdc83...20a8e.

    Edge captured:
      - Long-only directional bursts on high-beta alt perps (CHIP, ENA, XPL
        all had ~100% win rate in the wallet sample).
      - Entries clustered around US pre-open / cash-open hours (13:00-15:00
        UTC) on Tue/Wed.
      - Quick profit takes within hours; hard time stop near 5 days; soft
        capitulation stop on adverse moves (approximated here as a real
        protective stop because Freqtrade can't replicate 'no hard stop').

    Skipped:
      - xyz:MSFT and xyz:HIMS (non-alphanumeric ticker prefix; not on HL
        as alphanumeric perps usable in this form, and they were the loss
        engine of the wallet anyway).
      - Short trades (wallet never shorted in sample window).
    """

    INTERFACE_VERSION = 3

    timeframe = "15m"
    can_short = False

    # Wallet typical winner exits in 2-6h; let ROI ladder mirror that.
    minimal_roi = {
        "0": 0.08,
        "60": 0.04,
        "240": 0.02,
        "1440": 0.005,
    }

    # Wallet had no hard stop but ate ~$660 worst loss on ~$13k notional
    # ≈ -5%. Use that as a protective floor.
    stoploss = -0.05

    trailing_stop = True
    trailing_stop_positive = 0.02
    trailing_stop_positive_offset = 0.04
    trailing_only_offset_is_reached = True

    # Hard time stop ~ 5 days (wallet p95 hold 4.9d, max 5.7d). 15m * 480 = 5d.
    process_only_new_candles = True
    use_exit_signal = True
    exit_profit_only = False
    ignore_roi_if_entry_signal = False

    startup_candle_count: int = 200

    # --- Hyperparameters (kept simple, one or two load-bearing filters) ---
    ema_fast_len = IntParameter(8, 30, default=20, space="buy", optimize=False)
    ema_slow_len = IntParameter(40, 120, default=60, space="buy", optimize=False)
    breakout_len = IntParameter(10, 40, default=20, space="buy", optimize=False)
    rsi_len = IntParameter(7, 21, default=14, space="buy", optimize=False)
    rsi_min = DecimalParameter(40.0, 60.0, default=50.0, space="buy", optimize=False)
    max_hold_bars = IntParameter(96, 600, default=480, space="sell", optimize=False)

    def populate_indicators(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        df = dataframe

        # EMAs (inline, vectorized).
        df["ema_fast"] = df["close"].ewm(span=int(self.ema_fast_len.value), adjust=False).mean()
        df["ema_slow"] = df["close"].ewm(span=int(self.ema_slow_len.value), adjust=False).mean()

        # RSI (Wilder's smoothing approximated with ewm alpha=1/n).
        n = int(self.rsi_len.value)
        delta = df["close"].diff()
        up = delta.clip(lower=0.0)
        down = -delta.clip(upper=0.0)
        roll_up = up.ewm(alpha=1.0 / n, adjust=False).mean()
        roll_dn = down.ewm(alpha=1.0 / n, adjust=False).mean()
        rs = roll_up / roll_dn.replace(0.0, np.nan)
        df["rsi"] = 100.0 - (100.0 / (1.0 + rs))
        df["rsi"] = df["rsi"].fillna(50.0)

        # Donchian-style breakout high (prior N bars, exclusive of current).
        bl = int(self.breakout_len.value)
        df["hh"] = df["high"].rolling(bl).max().shift(1)

        # Rolling volume baseline -> require participation above average
        # (proxy for the wallet's taker-burst entries).
        df["vol_ma"] = df["volume"].rolling(20).mean()

        # Session timing: wallet was heavily 13:00-15:00 UTC active.
        ts = pd.to_datetime(df["date"], utc=True)
        df["hour"] = ts.dt.hour
        df["dow"] = ts.dt.dayofweek  # 0=Mon

        # Bars since dataframe start to enforce a max-hold time stop later.
        df["bar_idx"] = np.arange(len(df))

        return df

    def populate_entry_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        df = dataframe

        trend_up = df["ema_fast"] > df["ema_slow"]
        breakout = df["close"] > df["hh"]
        rsi_ok = df["rsi"] >= float(self.rsi_min.value)
        vol_ok = df["volume"] > df["vol_ma"]

        # Session window: 06, 12-15, 23 UTC were the wallet's hot hours.
        # Keep it loose: any of the high-activity hours qualifies. This is
        # the single load-bearing filter beyond the breakout itself, chosen
        # because the wallet's 15:00 UTC hour alone was 37% of all fills.
        session_ok = df["hour"].isin([6, 12, 13, 14, 15, 23])

        long_cond = trend_up & breakout & rsi_ok & vol_ok & session_ok

        df.loc[long_cond, "enter_long"] = 1
        df.loc[long_cond, "enter_tag"] = "breakout_session"

        return df

    def populate_exit_trend(self, dataframe: pd.DataFrame, metadata: dict) -> pd.DataFrame:
        df = dataframe

        # Momentum failure: fast EMA rolls under slow EMA OR RSI loses 45.
        trend_break = df["ema_fast"] < df["ema_slow"]
        rsi_weak = df["rsi"] < 45.0

        exit_cond = trend_break | rsi_weak
        df.loc[exit_cond, "exit_long"] = 1
        df.loc[exit_cond, "exit_tag"] = "momentum_fade"

        return df
Backtest custom range
Window Pair Status Trades Strategy PnL Wallet PnL Sharpe Max DD
validation 2026-04-11 → 2026-05-11 CHIP + ENA + XPL
15m
Completed 26 7.18 0.072% 2479.09 1.63 0.17% View →
validation 2026-04-11 → 2026-05-11 CHIP + ENA + XPL
15m
Failed 2479.09 View →
validation 2026-04-11 → 2026-05-11 CHIP + ENA + XPL
15m
Failed 2479.09 View →
Raw feature profile
{
  "pnl": {
    "losers": 50,
    "winners": 105,
    "win_rate": 0.677,
    "avg_loser_usd": -73.08,
    "closing_fills": 155,
    "profit_factor": 1.678,
    "avg_winner_usd": 58.41,
    "expectancy_usd": 15.9941,
    "largest_win_usd": 1214.96,
    "largest_loss_usd": -662.61,
    "closed_pnl_total_usd": 2479.09
  },
  "fees": {
    "maker_pct": 0.142,
    "total_fees_usd": 144.15,
    "avg_fee_per_fill_usd": 0.4435
  },
  "rhythm": {
    "fills_by_dow": {
      "Friday": 38,
      "Monday": 47,
      "Sunday": 14,
      "Tuesday": 92,
      "Wednesday": 134
    },
    "fills_by_hour_utc": {
      "0": 11,
      "1": 17,
      "4": 10,
      "5": 25,
      "6": 33,
      "8": 19,
      "12": 23,
      "13": 38,
      "15": 119,
      "23": 30
    },
    "quietest_hour_utc": 4,
    "most_active_hour_utc": 15
  },
  "window": {
    "to": "2026-05-11T12:09:28Z",
    "days": 30.0,
    "from": "2026-04-11T12:09:28Z"
  },
  "account": {
    "leverage": null,
    "snapshot_at": "2026-05-11T12:09:26Z",
    "open_positions": 0,
    "margin_used_usd": 0.0,
    "current_value_usd": 0.0
  },
  "funding": {
    "funding_payments": 222,
    "total_funding_usd": -133.37,
    "funding_vs_trading_pnl": -0.054,
    "avg_funding_per_payment_usd": -0.6008
  },
  "trading": {
    "buy_count": 170,
    "sell_count": 155,
    "total_fills": 325,
    "last_fill_at": "2026-04-27T13:45:02Z",
    "fills_per_day": 22.73,
    "first_fill_at": "2026-04-13T06:31:45Z",
    "buy_sell_ratio": 1.097,
    "distinct_assets": 8,
    "total_volume_usd": 627624.9,
    "avg_fill_size_usd": 1931.15,
    "median_fill_size_usd": 629.91
  },
  "drawdown": {
    "max_drawdown_at": "2026-04-22T06:28:46Z",
    "max_drawdown_usd": -2190.43,
    "ending_cumulative_pnl_usd": 2479.09
  },
  "asset_mix": {
    "top_assets": [
      {
        "asset": "xyz:MSFT",
        "fills": 65,
        "win_rate": 0.41,
        "volume_pct": 0.4,
        "volume_usd": 251036.44,
        "closed_pnl_usd": -975.23
      },
      {
        "asset": "CHIP",
        "fills": 73,
        "win_rate": 0.682,
        "volume_pct": 0.1602,
        "volume_usd": 100515.7,
        "closed_pnl_usd": 2563.49
      },
      {
        "asset": "XPL",
        "fills": 72,
        "win_rate": 1.0,
        "volume_pct": 0.0994,
        "volume_usd": 62411.67,
        "closed_pnl_usd": 365.05
      },
      {
        "asset": "xyz:MU",
        "fills": 10,
        "win_rate": 1.0,
        "volume_pct": 0.0973,
        "volume_usd": 61037.32,
        "closed_pnl_usd": 173.91
      },
      {
        "asset": "xyz:HIMS",
        "fills": 11,
        "win_rate": 0.0,
        "volume_pct": 0.079,
        "volume_usd": 49605.1,
        "closed_pnl_usd": -1214.56
      },
      {
        "asset": "ENA",
        "fills": 44,
        "win_rate": 1.0,
        "volume_pct": 0.0786,
        "volume_usd": 49308.23,
        "closed_pnl_usd": 2366.09
      },
      {
        "asset": "SYRUP",
        "fills": 28,
        "win_rate": 0.0,
        "volume_pct": 0.0666,
        "volume_usd": 41829.71,
        "closed_pnl_usd": -975.87
      },
      {
        "asset": "ZRO",
        "fills": 22,
        "win_rate": 1.0,
        "volume_pct": 0.0189,
        "volume_usd": 11880.72,
        "closed_pnl_usd": 176.21
      }
    ],
    "distinct_assets": 8,
    "concentration_hhi": 0.2222
  },
  "pnl_curve": [
    {
      "t": "2026-04-14T05:43:42Z",
      "pnl": 18.98
    },
    {
      "t": "2026-04-14T05:43:44Z",
      "pnl": 252.96
    },
    {
      "t": "2026-04-14T05:43:49Z",
      "pnl": 317.57
    },
    {
      "t": "2026-04-14T05:43:49Z",
      "pnl": 357.85
    },
    {
      "t": "2026-04-14T05:43:49Z",
      "pnl": 411.91
    },
    {
      "t": "2026-04-14T05:43:49Z",
      "pnl": 474.69
    },
    {
      "t": "2026-04-14T05:43:52Z",
      "pnl": 550.6
    },
    {
      "t": "2026-04-14T05:43:52Z",
      "pnl": 903.21
    },
    {
      "t": "2026-04-14T15:28:48Z",
      "pnl": 961.83
    },
    {
      "t": "2026-04-14T15:28:48Z",
      "pnl": 1049.61
    },
    {
      "t": "2026-04-17T13:25:15Z",
      "pnl": 1083.17
    },
    {
      "t": "2026-04-17T13:25:15Z",
      "pnl": 1087.72
    },
    {
      "t": "2026-04-17T13:25:15Z",
      "pnl": 1106.02
    },
    {
      "t": "2026-04-17T13:25:15Z",
      "pnl": 1120.2
    },
    {
      "t": "2026-04-17T13:25:15Z",
      "pnl": 1141.43
    },
    {
      "t": "2026-04-17T13:25:15Z",
      "pnl": 1180.08
    },
    {
      "t": "2026-04-17T13:25:15Z",
      "pnl": 1207.69
    },
    {
      "t": "2026-04-19T23:28:18Z",
      "pnl": 1321.29
    },
    {
      "t": "2026-04-19T23:28:18Z",
      "pnl": 1407.79
    },
    {
      "t": "2026-04-19T23:28:18Z",
      "pnl": 1616.6
    },
    {
      "t": "2026-04-19T23:28:18Z",
      "pnl": 2634.82
    },
    {
      "t": "2026-04-21T01:00:25Z",
      "pnl": 2924.34
    },
    {
      "t": "2026-04-21T01:00:25Z",
      "pnl": 2962.44
    },
    {
      "t": "2026-04-21T01:00:25Z",
      "pnl": 3018.05
    },
    {
      "t": "2026-04-21T01:00:25Z",
      "pnl": 3056.88
    },
    {
      "t": "2026-04-21T08:51:35Z",
      "pnl": 2806.37
    },
    {
      "t": "2026-04-21T08:51:35Z",
      "pnl": 2508.69
    },
    {
      "t": "2026-04-21T08:51:35Z",
      "pnl": 2307.16
    },
    {
      "t": "2026-04-21T08:51:35Z",
      "pnl": 2260.28
    },
    {
      "t": "2026-04-21T08:51:35Z",
      "pnl": 2105.4
    },
    {
      "t": "2026-04-22T06:28:46Z",
      "pnl": 1609.11
    },
    {
      "t": "2026-04-22T06:28:46Z",
      "pnl": 890.84
    },
    {
      "t": "2026-04-22T06:30:39Z",
      "pnl": 898.97
    },
    {
      "t": "2026-04-22T12:27:26Z",
      "pnl": 1125.35
    },
    {
      "t": "2026-04-22T12:27:26Z",
      "pnl": 1268.75
    },
    {
      "t": "2026-04-22T12:27:26Z",
      "pnl": 3196.36
    },
    {
      "t": "2026-04-22T12:27:26Z",
      "pnl": 3763.63
    },
    {
      "t": "2026-04-22T15:01:03Z",
      "pnl": 3812.28
    },
    {
      "t": "2026-04-22T15:01:03Z",
      "pnl": 3870.69
    },
    {
      "t": "2026-04-22T15:01:03Z",
      "pnl": 3892.16
    },
    {
      "t": "2026-04-22T15:03:12Z",
      "pnl": 3857.84
    },
    {
      "t": "2026-04-22T15:03:23Z",
      "pnl": 3753.81
    },
    {
      "t": "2026-04-22T15:14:02Z",
      "pnl": 3754.76
    },
    {
      "t": "2026-04-22T15:14:22Z",
      "pnl": 3754.05
    },
    {
      "t": "2026-04-22T15:14:22Z",
      "pnl": 3750.64
    },
    {
      "t": "2026-04-22T15:14:22Z",
      "pnl": 3744.52
    },
    {
      "t": "2026-04-22T15:14:22Z",
      "pnl": 3740.3
    },
    {
      "t": "2026-04-22T15:14:22Z",
      "pnl": 3738.33
    },
    {
      "t": "2026-04-22T15:51:08Z",
      "pnl": 3616.83
    },
    {
      "t": "2026-04-27T13:45:02Z",
      "pnl": 3525.5
    },
    {
      "t": "2026-04-27T13:45:02Z",
      "pnl": 2919.21
    },
    {
      "t": "2026-04-27T13:45:02Z",
      "pnl": 2627.18
    },
    {
      "t": "2026-04-27T13:45:02Z",
      "pnl": 2479.09
    }
  ],
  "positions": {
    "holds_observed": 14,
    "avg_hold_seconds": 132214.2,
    "max_hold_seconds": 495865.49,
    "p95_hold_seconds": 424187.56,
    "median_hold_seconds": 56446.1
  }
}
Agent Status Duration Input Output Cache R / W
classifier completed 9.0s 461 559 0 / 5,365
synthesizer completed 43.1s 8,669 2,811 5,077 / 6,285
narrator completed 16.5s 3,455 1,212 0 / 4,467
coder completed 31.4s 3,480 3,184 0 / 5,972