Overall Statistics |
Total Trades 22 Average Win 1.79% Average Loss -6.00% Compounding Annual Return -100.000% Drawdown 74.700% Expectancy -0.900 Net Profit -53.780% Sharpe Ratio -0.383 Probabilistic Sharpe Ratio 18.846% Loss Rate 92% Win Rate 8% Profit-Loss Ratio 0.30 Alpha -0.827 Beta 0.863 Annual Standard Deviation 2.608 Annual Variance 6.803 Information Ratio -0.308 Tracking Error 2.599 Treynor Ratio -1.156 Total Fees $62.90 Estimated Strategy Capacity $130000000.00 Lowest Capacity Asset CL XYME7AM671S1 |
# CrudeOilWTI TrueRange from datetime import timedelta from collections import deque class LogicalBrownKoala(QCAlgorithm): def Initialize(self): self.SetStartDate(2022, 4, 15) self.SetCash(100000) future = self.AddFuture(Futures.Energies.CrudeOilWTI, Resolution.Minute) future.SetFilter(timedelta(10), timedelta(180)) self.slow_sma = None self.slow_sma_period = 25 self.fast_sma = None self.fast_sma_period = 12 self.CCIPeriod = 30 self.CCIupperBound = 100 self.CCIlowerBound = -100 self.volume_sma_period = 30 self.consolidator_by_symbol = {} def OnData(self, slice): stop_time_start = self.Time.replace(hour=15, minute=00) stop_time_end = self.Time.replace(hour=16, minute=30) if self.Time > stop_time_end or self.Time < stop_time_start: return for chain in slice.FutureChains.Values: contracts = chain.Contracts if len(contracts) == 0: continue sorted_by_oi_contracts = sorted(contracts.Values, key=lambda k: k.OpenInterest, reverse=True) popular_contract = sorted_by_oi_contracts[0] if popular_contract.Symbol not in self.consolidator_by_symbol: Consolidator = TradeBarConsolidator(timedelta(minutes=3)) self.consolidator_by_symbol[popular_contract.Symbol] = Consolidator self.slow_sma = LinearWeightedMovingAverage(self.slow_sma_period) self.RegisterIndicator(popular_contract.Symbol, self.slow_sma, Consolidator) self.fast_sma = LinearWeightedMovingAverage(self.fast_sma_period) self.RegisterIndicator(popular_contract.Symbol, self.fast_sma, Consolidator) self.volume_sma = LinearWeightedMovingAverage(self.fast_sma_period) self.RegisterIndicator(popular_contract.Symbol, self.volume_sma, Consolidator, Field.Volume) self.cci = self.CCI(popular_contract.Symbol, self.CCIPeriod, MovingAverageType.Simple, Resolution.Daily) self.RegisterIndicator(popular_contract.Symbol, self.cci, Consolidator) self.true_range = True_Range("TrueRange", 2) self.RegisterIndicator(popular_contract.Symbol, self.true_range, Consolidator) self.Plot("Indicator", "TrueRange", self.true_range.Current.Value) ''' self.Plot("Indicator", "SMA slow", self.slow_sma.Current.Value) self.Plot("Indicator", "SMA fast", self.fast_sma.Current.Value) self.Plot("Indicator 2", "SMA Volume", self.volume_sma.Current.Value) self.Plot("CCI", "CCI value", self.cci.Current.Value) ''' if self.slow_sma.Current.Value > self.fast_sma.Current.Value: self.SetHoldings(popular_contract.Symbol, 1) class True_Range(PythonIndicator): def __init__(self, name, period): self.Name = name self.Value = None self.period = period self.WarmUpPeriod = period self.Time = datetime.min self.queue_close = deque(maxlen=period) self.queueTime = deque(maxlen=period) def Update(self, input): self.queue_close.appendleft(input.Close) self.queueTime.appendleft(input.EndTime) self.Time = input.EndTime count = len(self.queue_close) if self.queue_close[0] > input.High: TH = self.queue_close[0] else: TH = input.High if self.queue_close[0] < input.Low: TL = self.queue_close[0] else: TL = input.Low self.Value = TH - TL self.IsReady == self.queue_close.maxlen return self.IsReady