Overall Statistics
Total Orders
27
Average Win
6.42%
Average Loss
-1.92%
Compounding Annual Return
11.704%
Drawdown
10.900%
Expectancy
2.005
Start Equity
100000
End Equity
178764.19
Net Profit
78.764%
Sharpe Ratio
0.484
Sortino Ratio
0.391
Probabilistic Sharpe Ratio
33.024%
Loss Rate
31%
Win Rate
69%
Profit-Loss Ratio
3.34
Alpha
0
Beta
0
Annual Standard Deviation
0.097
Annual Variance
0.009
Information Ratio
0.868
Tracking Error
0.097
Treynor Ratio
0
Total Fees
$217.03
Estimated Strategy Capacity
$2600000.00
Lowest Capacity Asset
DBC TFVSB03UY0DH
Portfolio Turnover
0.68%
Drawdown Recovery
809
from AlgorithmImports import *
import numpy as np

class CommodityCtaMotorDV19(QCAlgorithm):
    def initialize(self):
        # 1. Configuração de Capital Base Seguro
        self.set_start_date(2021, 1, 1)
        self.set_end_date(2026, 6, 1)
        self.set_cash(100000)
        
        self.set_brokerage_model(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)
        
        # Cesta Macro Otimizada
        self.dbc = self.add_equity("DBC", Resolution.Daily).symbol
        self.gld = self.add_equity("GLD", Resolution.Daily).symbol
        self.assets = [self.dbc, self.gld]
        
        # Canais de Breakout Longos (Turtle Trading Antirruído)
        self.entry_window = 42 # Entrada na máxima de 2 meses
        self.exit_window = 21  # Saída na mínima de 1 mês
        
        # Execução síncrona na quinta-feira de manhã
        self.schedule.on(self.date_rules.every(DayOfWeek.Thursday), self.time_rules.after_market_open("DBC", 30), self.rebalance)
        self.set_warm_up(60, Resolution.Daily)

    def on_data(self, data: Slice):
        pass # Travado contra ruído diário

    def rebalance(self):
        if self.is_warming_up: return
        
        for symbol in self.assets:
            # Puxa o histórico de fechamentos para o canal
            history = self.history(symbol, self.entry_window + 1, Resolution.Daily)
            if history.empty or len(history) < (self.entry_window + 1): continue
            
            # Isola os preços passados tirando o tick atual de agora
            closes = history['close'].values[:-1]
            current_price = self.securities[symbol].price
            
            # Calcula as réguas do canal
            high_entry = np.max(closes[-self.entry_window:])
            low_exit = np.min(closes[-self.exit_window:])
            
            # --- MODELO DE EXECUÇÃO ESCALADO ---
            if current_price >= high_entry:
                if not self.portfolio[symbol].invested:
                    # CORREÇÃO: Aloca 48% para esmagar o cash drag e usar o capital real
                    self.set_holdings(symbol, 0.48)
            elif current_price <= low_exit:
                if self.portfolio[symbol].invested:
                    self.liquidate(symbol)