diff --git a/clp_hedger.py b/clp_hedger.py index 6a633b1..77f30c1 100644 --- a/clp_hedger.py +++ b/clp_hedger.py @@ -349,6 +349,34 @@ class ScalperHedger: logger.info(f"[DELTA] Delta-Zero Scalper Hedger initialized. Agent: {self.account.address}") + def get_dynamic_edge_proximity(self, price: Decimal) -> Decimal: + """ + Calculate dynamic edge proximity based on position value. + Larger positions need earlier warning (wider buffer). + Base: 4%. Scale: +4% per $10k value. Cap: 15%. + """ + base_pct = Decimal("0.04") + + # Estimate Position Value (Use Target Value as proxy for total risk) + # If strategy not ready, fallback to 0 + val_usd = self.strategy.target_value if self.strategy else Decimal("0") + + # Fallback to current hedge value if target not set + if val_usd == 0 and self.last_price: + pos = self.get_current_position(COIN_SYMBOL) + val_usd = abs(pos['size']) * self.last_price + + # Scaling: +0.04 (4%) for every 10,000 USD + # Factor = 0.04 / 10000 = 0.000004 + scaling_factor = Decimal("0.000004") + + add_pct = val_usd * scaling_factor + + total = base_pct + add_pct + + # Cap at 15% (0.15) and Min at 4% (0.04) + return max(base_pct, min(Decimal("0.15"), total)) + def _init_strategy(self, position_data: Dict): try: entry_amount0 = to_decimal(position_data.get('amount0_initial', 0)) @@ -693,7 +721,8 @@ class ScalperHedger: # Edge Proximity Check if active_pos.get('status') == 'OPEN': - position_edge_proximity = POSITION_OPEN_EDGE_PROXIMITY_PCT + # Dynamic Proximity Calculation + position_edge_proximity = self.get_dynamic_edge_proximity(price) range_width = self.strategy.high_range - self.strategy.low_range distance_from_bottom = price - self.strategy.low_range @@ -706,12 +735,11 @@ class ScalperHedger: if is_near_bottom or is_near_top: bypass_cooldown = True - override_reason = f"EDGE PROXIMITY ({position_edge_proximity*100:.1f}% edge)" + override_reason = f"EDGE PROXIMITY ({position_edge_proximity*100:.1f}% dyn-edge)" if is_near_bottom: override_reason += f" ({distance_from_bottom:.2f} from bottom)" else: override_reason += f" ({distance_from_top:.2f} from top)" - # Large Hedge Check if not bypass_cooldown: if diff_abs > (rebalance_threshold * LARGE_HEDGE_MULTIPLIER): diff --git a/clp_scalper_hedger.py b/clp_scalper_hedger.py index ca2e64f..c6f2ff3 100644 --- a/clp_scalper_hedger.py +++ b/clp_scalper_hedger.py @@ -466,6 +466,32 @@ class ScalperHedger: logging.info(f"[TRIG] Dynamic Protection: Volatility Multiplier {DYNAMIC_THRESHOLD_MULTIPLIER}x | Trade Cooldown {MIN_TIME_BETWEEN_TRADES}s | Max Hedge {MAX_HEDGE_MULTIPLIER*100:.0f}%") logging.info(f"[INFO] Uniswap spread monitoring removed for cleaner delta-zero hedging") + def get_dynamic_edge_proximity(self, price): + """ + Calculate dynamic edge proximity based on position value. + Larger positions need earlier warning (wider buffer). + Base: 4%. Scale: +4% per $10k value. Cap: 15%. + """ + base_pct = 0.04 + + # Estimate Position Value (Use Target Value as proxy for total risk) + val_usd = self.strategy.target_value if self.strategy else 0.0 + + # Fallback to current hedge value if target not set + if val_usd == 0 and self.last_price: + pos = self.get_current_position(COIN_SYMBOL) + val_usd = abs(pos['size']) * self.last_price + + # Scaling: +0.04 (4%) for every 10,000 USD + scaling_factor = 0.000004 + + add_pct = val_usd * scaling_factor + + total = base_pct + add_pct + + # Cap at 15% (0.15) and Min at 4% (0.04) + return max(base_pct, min(0.15, total)) + def _init_strategy(self, position_data): try: entry_amount0 = position_data.get('amount0_initial', 0) @@ -1071,8 +1097,8 @@ class ScalperHedger: elif (hasattr(active_pos, 'status') and active_pos.get('status') == 'OPEN'): - # Use position-aware edge proximity - position_edge_proximity = POSITION_OPEN_EDGE_PROXIMITY_PCT + # Use position-aware edge proximity (Dynamic) + position_edge_proximity = self.get_dynamic_edge_proximity(price) distance_from_bottom = price - clp_low_range distance_from_top = clp_high_range - price @@ -1084,7 +1110,7 @@ class ScalperHedger: if is_near_bottom or is_near_top: bypass_cooldown = True - override_reason = f"EDGE PROXIMITY ({position_edge_proximity*100:.1f}% edge)" + override_reason = f"EDGE PROXIMITY ({position_edge_proximity*100:.1f}% dyn-edge)" if is_near_bottom: override_reason += f" ({distance_from_bottom:.2f} from bottom)" else: