Overall Statistics
Total Trades
5
Average Win
0.35%
Average Loss
-23.71%
Compounding Annual Return
-23.335%
Drawdown
23.400%
Expectancy
-0.493
Net Profit
-23.437%
Sharpe Ratio
-0.871
Probabilistic Sharpe Ratio
0.000%
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
0.01
Alpha
-0.188
Beta
0.179
Annual Standard Deviation
0.176
Annual Variance
0.031
Information Ratio
-1.788
Tracking Error
0.196
Treynor Ratio
-0.855
Total Fees
$37.00
Estimated Strategy Capacity
$85000.00
Lowest Capacity Asset
GC XLJQILRHMG7X
import typing
from decimal import Decimal
from QuantConnect.Securities.Future import Future

class FiveOneFractalBreakoutCopy(QCAlgorithm):
    consolidator_by_symbol = {}

    def Initialize(self):
        self.SetStartDate(2021, 1, 1)  # Set Start Date
        self.SetCash(100000)  # Set Strategy Cash
        from future_set_up import FutureSetUp
        newFutureSetUp = FutureSetUp(self)
        self.SetSecurityInitializer(newFutureSetUp.OpenInterestSecurityInitializer)
        
        self.contracts = []
        self.symbolData = dict()
        for ticker in [
        Futures.Metals.Gold,
        Futures.Energies.CrudeOilWTI,
        Futures.Metals.Copper,
        Futures.Energies.NaturalGas,
        Futures.Indices.NASDAQ100EMini]:
            future = self.AddFuture(ticker, Resolution.Minute)
            future.SetFilter(lambda x: x.FrontMonth().OnlyApplyFilterAtMarketOpen())
        
        # VARIABLES & LIST
        # THESE DICTIONARY NAMES CANNOT CHANGE. THE CUSTOM LIBRARY DEPENDS ON IT...
        self.rulesDict = {}
        self.bearFiveDict = {}
        self.bullFiveDict = {}
        self.bullOneDict = {}
        self.bearOneDict = {}
        self.FiveUpDict = {}
        self.FiveDownDict = {}
        self.first_lowDict = {}
        self.second_lowDict = {}
        self.first_highDict = {}
        self.second_highDict = {}
        #Used to check if the first trade in a thesis was a loser.
        self.bull_losing_outcomeDict = {}
        self.bear_losing_outcomeDict = {}
        #A set of variables used to limit re-entries to only happen once per thesis
        self.first_position_bullDict = {}
        self.second_position_bullDict = {}
        self.first_position_bearDict = {}
        self.second_position_bearDict = {}
        #Used for making sure re-entries happen on a new fractal
        self.entry_minuteDict = {}
        #DIRECTION VARIABLES
        self.supportDict = {}
        self.resistanceDict = {}
        self.breakoutDict = {}
        self.breakdownDict = {}
        # ORDER VARIABLES
        self.short_stopDict = {}
        self.second_short_stopDict = {}
        self.long_stopDict = {}
        self.second_long_stopDict = {}
        self.long_entryDict = {}
        self.second_long_entryDict = {}
        self.short_entryDict = {}
        self.second_short_entryDict = {}
        self.long_exitDict = {}
        self.second_long_exitDict = {}
        self.short_exitDict = {}
        self.second_short_exitDict = {}
        self.longOrdersDict = {}
        self.shortOrdersDict = {}
        self.partial_exit_fill_safety_longDict = {}
        self.partial_fill_liq_priceDict = {}
        self.partial_exit_fill_safety_shortDict = {}
        self.risk_targetDict = {}
        self.buying_powerDict = {}
        self.share_sizeDict = {}
        self.dollar_sizeDict = {}
        self.max_price_longDict = {}
        self.max_price_shortDict = {}
        self.trading_hoursDict = {}
        self.symbolEntryPriceDict = {}
        self.symbolStopPriceDict = {}
        self.symbolExitPriceDict = {}
        self.longDict = {}
        self.shortDict = {}
        self.portfolioAmmount = self.Portfolio.Cash
        
    def OnSecuritiesChanged(self, changes):
        for security in changes.AddedSecurities:
            contractString = str(security.Symbol)
            
            # Don't consolidate or add the actual future.
            if contractString[0] == "/":
                continue
            
            market = contractString.split()[0]
            
            # Don't add the same contract twice.
            if security.Symbol in self.consolidator_by_symbol.keys():
                continue
            
            # Create list of symbol strings.
            stringContracts = []
            for prevContract in self.consolidator_by_symbol.keys():
                stringContracts.append(str(prevContract))
            
            # Only allow one contract per Future to be added.
            if any(market in s for s in stringContracts):
                continue
            
            # Make check to ensure it's only adding valid contracts. 
            # When converting a symbol to a string the string length is normally 15 characters long for valid contracts.
            # This check is probably unnecessary.
            if (len(contractString) > 10):
                # Set the Rolling Windows for the contract
                self.symbolData[security.Symbol] = SymbolData()
                # Consolidate the contract
                consolidator = QuoteBarConsolidator(timedelta(minutes=5))
                consolidator.DataConsolidated += self.OnDataConsolidated
                self.SubscriptionManager.AddConsolidator(security.Symbol, consolidator)
                # Add contract consolidator to dictionary
                self.consolidator_by_symbol[security.Symbol] = consolidator
                # Add contract to contract list.
                self.contracts.append(security.Symbol)

    def OnDataConsolidated(self, sender, quoteBar):
        from onDataConsolidated import OnDataConsolidated
        newOnDataConsolidated = OnDataConsolidated(self)
        newOnDataConsolidated.RunOnDataConsolidated(quoteBar)
        
    def OnData(self, slice):
        from onData import OnData
        newOnData = OnData(self)
        newOnData.RunOnData(slice, "Future")
            
    def OnOrderEvent (self, orderEvent):
        from onOrderEvent import OnOrderEvent
        newOnOrderEvent = OnOrderEvent(self)
        newOnOrderEvent.RunOnOrderEvent(orderEvent, "Future")
            
class SymbolData(object):    
    def __init__(self):
        self.quickTradeBarWindow = RollingWindow[QuoteBar](5)
        self.longTradeBarWindow = RollingWindow[QuoteBar](5)
class FutureSetUp(QCAlgorithm):
    def __init__(self, context):
        self.context = context
        
    def OpenInterestSecurityInitializer(self, security):
        if security.Type == SecurityType.Future:
            history = self.context.History([security.Symbol], timedelta(1))
            if 'openinterest' in history:
                oi = OpenInterest(self.context.Time, security.Symbol,
                    history.openinterest.dropna().iloc[-1])
                security.SetMarketPrice(oi)
                
    def GrabFrontMonthContracts(self, slice):
        liquidContracts = []
        for chain in slice.FutureChains:
            chainValue = chain.Value
            contracts = chainValue.Contracts
            for contract in contracts.Values:
                liquidContracts.append(contract)
        
        if liquidContracts == None or len(liquidContracts) <= 0:
            return None
            
        else:
            return liquidContracts
        
    def SetContract(self, slice):
        liquidContracts = self.GrabFrontMonthContracts(slice)
        symbols = []
        
        if (liquidContracts == None):
            return None
        
        for contract in liquidContracts:
            contractString = str(contract.Symbol)
            market = contractString.split()[0]
            
            if contract.Symbol in self.context.contracts:
                continue
            
            stringContracts = []
            for prevContract in self.context.contracts:
                stringContracts.append(str(prevContract))
            
            if any(market in s for s in stringContracts):
                continue
                    
            self.context.contracts.append(contract.Symbol)
                
            symbols.append(contract.Symbol)
        
        return symbols
# Your New Python File