feat: apply #33B impulse trail + #34A skip hours 9,21 WIB
#33B Impulse Trail (position_manager.py): - Tighten trailing SL to 1.5x ATR when candle range > 1.5x ATR - Locks profit faster during volatile spikes (+$59, Sharpe 4.03) #34A Time-of-Hour Filter (main_live.py): - Skip entries at WIB hours 9 (02:00 UTC) and 21 (14:00 UTC) - Hour 9 = end NY session (low liquidity), Hour 21 = London-NY transition (whipsaw) - +$356 vs #31B, WR 82.6%, Sharpe 4.41, PF 2.43, DD 2.4% Cumulative live: $3,163 net, 614 trades, 82.6% WR, Sharpe 4.41 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+21
-2
@@ -340,9 +340,18 @@ class SmartPositionManager:
|
||||
if atr_val is not None and atr_val > 0:
|
||||
current_atr = atr_val
|
||||
|
||||
# #33B: Get last candle range for impulse detection
|
||||
last_candle_range = None
|
||||
if len(df_market) >= 1:
|
||||
last_row = df_market.tail(1)
|
||||
last_high = last_row["high"].item()
|
||||
last_low = last_row["low"].item()
|
||||
if last_high is not None and last_low is not None:
|
||||
last_candle_range = last_high - last_low
|
||||
|
||||
for row in positions.iter_rows(named=True):
|
||||
action = self._analyze_single_position(
|
||||
row, market_analysis, current_price, current_atr
|
||||
row, market_analysis, current_price, current_atr, last_candle_range
|
||||
)
|
||||
if action:
|
||||
actions.append(action)
|
||||
@@ -437,6 +446,7 @@ class SmartPositionManager:
|
||||
market: Dict,
|
||||
current_price: float,
|
||||
current_atr: float = None,
|
||||
last_candle_range: float = None,
|
||||
) -> Optional[PositionAction]:
|
||||
"""Analyze a single position and decide action."""
|
||||
ticket = pos["ticket"]
|
||||
@@ -575,8 +585,17 @@ class SmartPositionManager:
|
||||
)
|
||||
|
||||
# 6. Trailing stop (after trail_start pips)
|
||||
# #33B: Impulse detection — tighten trail when candle range > 1.5x ATR
|
||||
if pip_profit >= trail_start:
|
||||
trail_distance = trail_step * 0.1 # Convert to price
|
||||
is_impulse = False
|
||||
if last_candle_range is not None and current_atr is not None and current_atr > 0:
|
||||
if last_candle_range > current_atr * 1.5:
|
||||
is_impulse = True
|
||||
|
||||
active_trail_step = trail_step
|
||||
if is_impulse:
|
||||
active_trail_step = (current_atr * 1.5) / 0.1 # 1.5x ATR in pips
|
||||
trail_distance = active_trail_step * 0.1 # Convert to price
|
||||
|
||||
if is_buy:
|
||||
new_trail_sl = current_price - trail_distance
|
||||
|
||||
Reference in New Issue
Block a user