Overall Statistics
Total Orders
66
Average Win
0.27%
Average Loss
-0.40%
Compounding Annual Return
0.706%
Drawdown
1.000%
Expectancy
0.283
Start Equity
100000.00
End Equity
103750.44
Net Profit
3.750%
Sharpe Ratio
-4.459
Sortino Ratio
-1.134
Probabilistic Sharpe Ratio
17.954%
Loss Rate
24%
Win Rate
76%
Profit-Loss Ratio
0.69
Alpha
-0.032
Beta
0.002
Annual Standard Deviation
0.007
Annual Variance
0
Information Ratio
0.166
Tracking Error
0.063
Treynor Ratio
-13.955
Total Fees
$0.00
Estimated Strategy Capacity
$35000.00
Lowest Capacity Asset
XAUUSD 8I
Portfolio Turnover
1.86%
Drawdown Recovery
161
from AlgorithmImports import *

class GoldDeepSweepV5(QCAlgorithm):
    def initialize(self):
        # 1. Horizonte Temporal
        self.set_start_date(2021, 1, 1)
        self.set_end_date(2026, 6, 1)
        self.set_cash(100000)
        
        self.set_brokerage_model(BrokerageName.OandaBrokerage, AccountType.Margin)
        self.gold = self.add_cfd("XAUUSD", Resolution.Hour, Market.OANDA).symbol

        self.atr = self.atr(self.gold, 14)
        self.rsi = self.rsi(self.gold, 14, MovingAverageType.Wilders)

        # Matriz de Balizamento UTC
        self.asia_high = 0.0
        self.asia_low = 0.0
        self.asia_high_pool = []
        self.asia_low_pool = []
        
        # Flags de Caça Profunda
        self.deep_high_hunted = False
        self.deep_low_hunted = False
        
        # Estado de Posição
        self.entry_price = 0.0
        self.sl_price = 0.0
        self.tp_price = 0.0
        self.last_trade_day = -1
        
        self.set_warm_up(48, Resolution.Hour)

    def on_data(self, data: Slice):
        if self.time.hour == 17: return 
        if self.gold not in data or data[self.gold] is None: return
        
        if self.is_warming_up or not self.atr.is_ready or not self.rsi.is_ready: return

        close_price = data[self.gold].close
        high_price = data[self.gold].high
        low_price = data[self.gold].low
        quantity = self.portfolio[self.gold].quantity

        # ================= 1. MONTAGEM DO CAIXOTE ASIA (UTC) =================
        if self.time.hour == 22:
            self.asia_high_pool = [high_price]
            self.asia_low_pool = [low_price]
        elif (23 <= self.time.hour <= 23) or (0 <= self.time.hour <= 5):
            self.asia_high_pool.append(high_price)
            self.asia_low_pool.append(low_price)
            
        if self.time.hour == 6:
            if self.asia_high_pool and self.asia_low_pool:
                self.asia_high = max(self.asia_high_pool)
                self.asia_low = min(self.asia_low_pool)
                self.deep_high_hunted = False
                self.deep_low_hunted = False

        # ================= 2. GESTÃO DE SAÍDA =================
        if quantity != 0:
            if quantity > 0:
                if close_price <= self.sl_price or close_price >= self.tp_price:
                    self.liquidate(self.gold)
                    self.reset_trade_state()
            elif quantity < 0:
                if close_price >= self.sl_price or close_price <= self.tp_price:
                    self.liquidate(self.gold)
                    self.reset_trade_state()
            return

        # ================= 3. DISPARO DA ARMADILHA CORRIGIDA =================
        if not (7 <= self.time.hour <= 16): return
        if self.time.day == self.last_trade_day: return
        if self.asia_high == 0 or self.asia_low == 0: return

        atr_val = self.atr.current.value
        if atr_val <= 0: return

        # FILTRO CRÍTICO: Exige que o preço fure a máxima da Ásia por pelo menos 0.7 * ATR
        if high_price >= (self.asia_high + (atr_val * 0.7)):
            self.deep_high_hunted = True
            self.deep_low_hunted = False

        # GATILHO SHORT: Retorno com RSI em exaustão vendedora na hora da falha
        if self.deep_high_hunted and close_price < self.asia_high and self.rsi.current.value >= 65:
            self.entry_price = close_price
            self.sl_price = close_price + (atr_val * 2.5) # Espaço para o retest
            self.tp_price = (self.asia_high + self.asia_low) / 2.0 
            
            self.set_holdings(self.gold, -0.55)
            self.deep_high_hunted = False
            self.last_trade_day = self.time.day
            return

        # FILTRO CRÍTICO LONG: Exige espetada funda para baixo
        if low_price <= (self.asia_low - (atr_val * 0.7)):
            self.deep_low_hunted = True
            self.deep_high_hunted = False

        # GATILHO LONG
        if self.deep_low_hunted and close_price > self.asia_low and self.rsi.current.value <= 35:
            self.entry_price = close_price
            self.sl_price = close_price - (atr_val * 2.5)
            self.tp_price = (self.asia_high + self.asia_low) / 2.0
            
            self.set_holdings(self.gold, 0.55)
            self.deep_low_hunted = False
            self.last_trade_day = self.time.day

    def reset_trade_state(self):
        self.entry_price = 0.0
        self.sl_price = 0.0
        self.tp_price = 0.0