| 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)