From a5cf3fe5831de0574b42028dd23c06b91a8a1402 Mon Sep 17 00:00:00 2001 From: ramseshk <45832522+ramseshk@users.noreply.github.com> Date: Wed, 12 Aug 2026 12:34:51 +0800 Subject: [PATCH] fix: spot-perp basis floating-point EPS, NORMAL regime fallback, realistic fee defaults --- strategies/regime_ensemble.py | 13 +++++++++++++ strategies/spot_perp_basis.py | 14 ++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/strategies/regime_ensemble.py b/strategies/regime_ensemble.py index d194080..1856ee9 100644 --- a/strategies/regime_ensemble.py +++ b/strategies/regime_ensemble.py @@ -107,6 +107,19 @@ STRATEGY_REGIME_AFFINITY = { "obi": 0.1, "mean_rev": 0.1, }, + "NORMAL": { + "pairs": 0.7, + "cross_sectional": 0.6, + "hurst_vpin": 0.5, + "momentum": 0.5, + "obi": 0.5, + "mean_rev": 0.5, + "grid_mm": 0.5, + "as_mm": 0.4, + "funding_arb": 0.3, + "queue_imbalance": 0.4, + "iceberg": 0.4, + }, } diff --git a/strategies/spot_perp_basis.py b/strategies/spot_perp_basis.py index f260b12..ac6f014 100644 --- a/strategies/spot_perp_basis.py +++ b/strategies/spot_perp_basis.py @@ -30,6 +30,8 @@ import numpy as np logger = logging.getLogger(__name__) +EPS = 1e-10 + class SpotPerpBasisArb: """Delta-neutral spot-perpetual basis arbitrage. @@ -47,13 +49,13 @@ class SpotPerpBasisArb: def __init__( self, - entry_threshold_bps: float = 3.0, + entry_threshold_bps: float = 5.0, exit_threshold_bps: float = 1.0, max_hold_hours: float = 48.0, size_usd: float = 1000.0, - spot_fee_rate: float = 0.0010, - perp_fee_rate: float = 0.0007, - min_expected_profit_bps: float = 1.5, + spot_fee_rate: float = 0.0004, + perp_fee_rate: float = 0.00015, + min_expected_profit_bps: float = 1.0, ): self.entry_threshold = entry_threshold_bps / 10000 # bps → decimal self.exit_threshold = exit_threshold_bps / 10000 @@ -112,7 +114,7 @@ class SpotPerpBasisArb: funding_apr = abs(funding_rate) * 365 * 3 # 8h → annual funding_profit = funding_apr * (self.max_hold_hours / (365 * 24)) - if not in_position and abs(basis) > self.entry_threshold and expected_profit > self.min_expected_profit: + if not in_position and abs(basis) > self.entry_threshold and expected_profit >= self.min_expected_profit - EPS: if basis > 0: return { "action": "SELL_PERP_BUY_SPOT", @@ -237,7 +239,7 @@ def multi_asset_basis_scan( continue basis = (perp - spot) / spot - if abs(basis) > entry_threshold_bps / 10000: + if abs(basis) >= entry_threshold_bps / 10000 - EPS: opportunities.append({ "coin": coin, "spot": spot,