9.1 KiB
Analysis Request: Optimization of Rebalance Threshold with ATR
Status: Completed Date: 2025-12-21 Priority: Medium
1. User Description & Query
Goal: Optimize rebalance_threshold in clp_hedger.py to save hedging trading costs.
Context: Volatility changes over the week (e.g., lower on weekends, higher on weekdays/events).
Desired Behavior: rebalance_threshold should dynamically adjust based on market conditions (volatility).
Specific Questions
- Time frame and period of ATR to be used?
- Impact of CLP Range (+/- 0.5% to 3.5%)?
- Impact of CLP Size (1k - 10k)?
- Other metrics?
NEW
Specific Questions / taks
- find rebalace_threshold to low volality markets
References
- Files: \01\clp_hedger.log, \01\hedge_status.json, \01\uniswap_manager.log
2. Agent Summary
- Objective: Implement a dynamic rebalancing threshold mechanism that widens during high volatility (to avoid noise trading) and tightens during low volatility (to maintain precise hedging), while respecting the constraints of range width and position size.
- Key Constraints:
- Cost vs. Risk: Reducing trades saves fees but increases delta exposure risk.
- Latency: Calculation must be lightweight (tick-by-tick loop).
- Safety: Threshold must never be so wide that it allows the position to become dangerously unhedged.
3. Main Analysis
3.1 Codebase Investigation
- Current Logic:
rebalance_thresholdis currentlymax(MIN_THRESHOLD_ETH, max_potential_eth * 0.05).- It effectively targets rebalancing when the delta deviation exceeds 5% of the max possible delta.
- There is a simple "Volatility Adjustment" that multiplies the threshold by
DYNAMIC_THRESHOLD_MULTIPLIER(1.2x or 1.3x) if the instantaneous price change > 0.3%.
- Data Availability:
clp_hedger.pymaintainsself.price_history(list of recent prices).- It runs on a
CHECK_INTERVAL(1s loop).
3.2 Strategy & Logic Design
A. Volatility Metric (ATR Proxy)
Since we are in a tight loop without external candle data, we should calculate an internal volatility metric.
- Method: "Rolling Standard Deviation" or "Average Absolute Deviation" of the last N ticks.
- Window: 5 minutes (300 ticks @ 1s interval) is a good balance between responsiveness and stability.
- Calculation:
volatility_pct = (current_price - moving_average) / moving_average.
B. Dynamic Threshold Formula
We want the threshold to scale with volatility, but be capped by the range width (risk).
- Base Threshold: Start with a tight base (e.g., 2% of max delta).
- Volatility Factor: Scaler based on
volatility_pct.- Low Vol (<0.05% move/min): Multiplier 1.0x.
- High Vol (>0.2% move/min): Multiplier up to 3.0x.
C. Addressing Specific Questions
-
Time Frame (ATR):
- Recommendation: Use a short-term volatility window (e.g., 5-15 minutes). Weekly/Daily ATR is too slow for a scalping hedger. If the market spikes now, we need to adjust now, not based on yesterday's range.
-
Impact of Range Width (+/- 0.5% vs 3.5%):
- Tight Range (0.5%): Gamma is extreme. Delta changes massively with small moves.
- Constraint: Threshold CANNOT be widened significantly, even if vol is high. Risk of exiting range unhedged is too high.
- Adjustment: Cap the dynamic multiplier. Max Threshold < 10% of Range Width.
- Wide Range (3.5%): Gamma is lower. Delta changes slowly.
- Adjustment: We can afford a much wider threshold to save fees.
- Tight Range (0.5%): Gamma is extreme. Delta changes massively with small moves.
-
Impact of Position Size (1k vs 10k):
- Small (1k): Slippage is negligible. Priority = Fee savings.
- Adjustment: Standard dynamic threshold.
- Large (10k): Liquidity is a risk.
- Adjustment: Use the "Edge Proximity" logic (already implemented). For the standard rebalance threshold, we might actually want to keep it tighter or standard to avoid needing to dump a huge delta all at once. Large positions prefer "averaging" out the hedge rather than one massive panic trade.
- Small (1k): Slippage is negligible. Priority = Fee savings.
-
Other Metrics:
- Funding Rate: If funding is paid to shorts, we might want to be slightly over-hedged (short). If paid to longs, we might minimize short duration. (Advanced optimization).
- Gas/Fee Costs: If Hyperliquid fees/gas are high (unlikely for HL), widen threshold.
4. Proposed Algorithm
def get_dynamic_threshold(self):
# 1. Calculate Volatility (Standard Deviation of last 300 ticks / 5 mins)
vol_pct = self.calculate_volatility()
# 2. Determine Multiplier
# Baseline vol might be 0.05% per minute.
# If vol is 0.15%, multiplier = 3x.
vol_multiplier = max(1.0, min(3.0, vol_pct / 0.0005))
# 3. Calculate Base Threshold (based on Range Width)
# Tighter range = smaller % allowed deviation
range_width_pct = (self.strategy.high_range - self.strategy.low_range) / self.strategy.low_range
base_threshold_pct = 0.03 # Start with 3% of max delta
# 4. Apply Multiplier
target_threshold_pct = base_threshold_pct * vol_multiplier
# 5. Apply Safety Cap (Range Dependent)
# Never allow threshold to exceed 10% of the total range width in delta terms
# (Simplified logic: Threshold shouldn't delay hedging until we are 20% through the range)
safety_cap = 0.10
final_threshold_pct = min(target_threshold_pct, safety_cap)
return final_threshold_pct
3.4 Technical Justification: Standard Deviation vs. ATR
I chose Standard Deviation (Volatility) over traditional ATR (Average True Range) for the implementation for the following reasons:
- Tick-Level Responsiveness: Std Dev operates on the rolling price history (last 300 ticks) and reacts immediately to volatility changes. ATR requires completed OHLC candles, which introduces a "closing delay."
- Architectural Simplicity: Calculating Std Dev only requires a list of prices (
self.price_history). ATR would require building a candle-management engine (tracking Highs/Lows/Closes per period), adding unnecessary complexity and potential latency. - Statistical Alignment: Std Dev measures dispersion from the mean. This is ideal for identifying "chop" (where we want to widen thresholds) vs. "trends." ATR measures range width but doesn't differentiate as clearly between choppy noise and directional moves in a tick-by-tick context.
- Performance: Rolling Std Dev on a fixed-size buffer is computationally efficient for a high-frequency loop checking every 1s.
5. Conclusion
To save costs without compromising safety:
- Switch from fixed 5% threshold to a dynamic 2-8% range.
- Drive the dynamic factor by short-term (5-min) volatility.
- Cap the threshold tightly for narrow ranges (0.5-1.0%) because Gamma risk outweighs fee savings.
- For large positions, rely on the existing "Edge Proximity" logic to handle liquidity risk, while using this volatility logic to optimize the "middle of the range" behavior.
6. Implementation Plan
- Step 1: Implement
calculate_volatility()inclp_hedger.py(usingnumpyor simple math onprice_history). - Step 2: Refactor
rebalance_thresholdlogic in the main loop to use the formula above. - Step 3: Add logging to track
Vol: X% | Threshold: Y%to verify behavior. - Step 4: Test with
TARGET_INVESTMENT_VALUE_USDC = 2000configuration to ensure it doesn't over-trade on weekends.
Findings & Implementation Update (2025-12-21)
4. Findings (Low Volatility)
- Context: Market was extremely quiet (Vol ~0.02% - 0.04%).
- Behavior: The bot correctly stayed IDLE for delta imbalances of ~4%.
- Issue: The "churn" trades (paying high fees for small rebalances) were still happening occasionally because the base threshold was fixed at 5%. In very low volatility (mean-reverting noise), a 5% imbalance often resolves itself without trading.
- Cost: Trading to fix a 5% imbalance costs spread + fees, which is often > the risk of that 5% imbalance growing.
5. Implemented Solution
We introduced a configurable BASE_REBALANCE_THRESHOLD_PCT flag to clp_hedger.py and raised the default for low-volatility regimes.
- New Flag:
BASE_REBALANCE_THRESHOLD_PCT - New Default: 0.08 (8%) (Increased from hardcoded 0.05).
- Logic:
# Ensure we satisfy PRICE_BUFFER_PCT (0.15%) minimum base_threshold_pct = max(BASE_REBALANCE_THRESHOLD_PCT, PRICE_BUFFER_PCT / range_width_pct if range_width_pct > 0 else BASE_REBALANCE_THRESHOLD_PCT) - Why: Widening the threshold in low volatility reduces "noise trading" significantly. 8% deviation is safe in a quiet market, whereas in a high vol market the dynamic multiplier (1.0x - 3.0x) would kick in to widen it further if needed, or the user can manually lower the base back to 5% for precision during events.
6. Conclusion
The optimization is complete. The bot is now less sensitive to small, non-threatening price drifts in quiet markets, which should directly reduce hedging costs and improve net profitability.