Repository Public
1"""Volatility-targeted trend: trend-following position, scaled down when realised volatility is high."""23import numpy as np45META = {6 "name": "vol_target_trend",7 "version": "2",8 "universe": ["ETH", "LINK", "AAVE"],9 "interval": "1h",10 "lookback": 1000,11 "params": {"fast": 72, "slow": 480, "vol_window": 168, "target_vol": 0.4},12}1314SECONDS_PER_YEAR = 365.0 * 86400.0151617def target_weights(data, params):18 fast, slow = int(params["fast"]), int(params["slow"])19 vol_window, target_vol = int(params["vol_window"]), float(params["target_vol"])20 n = len(data)21 weights = {}22 for symbol, df in data.items():23 close = df["close"].to_numpy()24 if len(close) < max(fast, slow, vol_window + 1) or fast >= slow or vol_window < 2:25 weights[symbol] = 0.026 continue27 if not close[-fast:].mean() > close[-slow:].mean():28 weights[symbol] = 0.029 continue30 bar_seconds = (df.index[-1] - df.index[-2]).total_seconds()31 log_returns = np.diff(np.log(close[-(vol_window + 1):]))32 realised = log_returns.std(ddof=1) * np.sqrt(SECONDS_PER_YEAR / bar_seconds)33 scale = min(1.0, target_vol / realised) if realised > 0 else 0.034 weights[symbol] = scale / n35 return weights36