SPB Git

Repository Public

strategy.py 2.0 KB 55 lines python

1"""Funding carry, perp leg only: short a perpetual whose funding is persistently positive and large (directional)."""23import numpy as np45META = {6    "name": "funding_carry_perp",7    "version": "1",8    "kind": "perp",9    "universe": ["BTC", "ETH", "SOL", "HYPE"],10    "interval": "1h",11    "lookback": 1100,12    "max_leverage": 2.0,13    "max_gross_exposure": 2.0,14    "params": {"window": 72, "z_window": 504, "min_rate_apr": 0.15, "persistence": 0.75, "z_full": 2.0,15               "gross": 1.0},16}1718SECONDS_PER_YEAR = 365.0 * 86400.0192021def carry_strength(df, window, z_window, min_rate_apr, persistence, z_full):22    """0..1: how strongly funding says 'longs are paying, persistently, more than usual'. 0 when it does not."""23    if "funding" not in df.columns or window < 2 or z_window < 2 * window or z_full <= 0:24        return 0.025    rate = df["funding"].to_numpy()26    if len(rate) < z_window or len(df) < 2:27        return 0.028    rate = rate[-z_window:]29    if np.isnan(rate).mean() > 0.1:                      # too many settlements missing to say anything30        return 0.031    rate = np.where(np.isnan(rate), 0.0, rate)32    recent = rate[-window:]33    bar_seconds = (df.index[-1] - df.index[-2]).total_seconds()34    apr = recent.mean() * SECONDS_PER_YEAR / bar_seconds35    if apr < min_rate_apr or (recent > 0).mean() < persistence:36        return 0.037    means = np.lib.stride_tricks.sliding_window_view(rate, window).mean(axis=1)38    spread = means.std(ddof=1)39    if not spread > 0:40        return 0.041    z = (means[-1] - means.mean()) / spread42    return float(min(max(z / z_full, 0.0), 1.0))434445def target_weights(data, params):46    window, z_window = int(params["window"]), int(params["z_window"])47    gross = float(params["gross"])48    n = len(data)49    weights = {}50    for symbol, df in data.items():51        strength = carry_strength(df, window, z_window, float(params["min_rate_apr"]), float(params["persistence"]),52                                  float(params["z_full"]))53        weights[symbol] = -strength * gross / n54    return weights55
Files main
Menu

Theme