Overall Statistics
Total Orders
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Start Equity
100000
End Equity
100000
Net Profit
0%
Sharpe Ratio
0
Sortino Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
-0.712
Tracking Error
0.143
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
Portfolio Turnover
0%
#region imports
from AlgorithmImports import *
#endregion
from QuantConnect.Indicators import MovingAverageConvergenceDivergence

class BootCampTask(QCAlgorithm):
    """
    BootCampTask algorithm trades the most liquid future contract of S&P 500 E-mini based on the MACD signal.
    It takes a long position when the MACD value is significantly less than the signal (suggesting an upward trend), 
    and a short position when the MACD value is significantly greater than the signal (suggesting a downward trend).
    It places corresponding stop loss and take profit orders for risk management.
    """

    def Initialize(self):
        """
        Initialize the algorithm with necessary parameters.
        """
        self.SetStartDate(2013, 12, 20)  # Set the algorithm start date
        self.SetEndDate(2014, 6, 21)     # Set the algorithm end date
        self.SetCash(1000000)             # Set the starting cash
        
        # Add the future contract for the S&P 500 E-mini and set filters for expiration range.
        self.spy = self.AddFuture(Futures.Indices.SP500EMini) 
        self.spy.SetFilter(5, 120)  # Only include contracts expiring in 5 to 120 days
        
        # Initialize variables to store the most liquid contract, the MACD indicator,
        # and order tickets for take profit and stop loss.
        self.oi_contract = None  # Most liquid contract based on open interest
        self.macd = None         # MACD indicator
        
        self.takeProfit = None   # Take profit order ticket
        self.stopLoss = None     # Stop loss order ticket
      
    def OnData(self, slice):
        """
        Event handler for new data.
        """
        # Iterate through each future chain in the data slice.
        for chain in slice.FutureChains:
            # Select contracts from the chain and sort them by open interest.
            contracts = sorted([contract for contract in chain.Value], 
                               key=lambda k: k.OpenInterest, reverse=True)
            
            # If there are no contracts, reset variables and break the loop.
            if len(contracts) == 0:
                self.oi_contract = None
                self.macd = None
                break
            
            # Pick the most liquid contract.
            contract = contracts[0]
            
            # If we have already stored the most liquid contract and it is unchanged, skip updates.
            if self.oi_contract is not None and contract.Symbol == self.oi_contract.Symbol:
                break
            
            # Update the most liquid contract and initialize the MACD indicator.
            self.oi_contract = contract
            self.macd = self.MACD(contract.Symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Minute)
        
        # If the MACD indicator is not ready, return early.
        if self.macd is None or not self.macd.IsReady:
            return
        
        # Define the trade logic for new positions.
        symbol = self.oi_contract.Symbol
        security = self.Securities[symbol]
        
        # Do not trade if we're already invested in this contract.
        if security.Invested:
            return
        
        price = security.Price
        tolerance = 0.003  # Tolerance for MACD signal deviation
        signalDeltaPercent = self.macd.Current.Value - self.macd.Signal.Current.Value
        
        # Determine the trading signal based on MACD and tolerance.
        if signalDeltaPercent < -tolerance:
            # If MACD is significantly below the signal line, go long.
            self.MarketOrder(symbol, 1)
            # Set take profit and stop loss orders.
            self.takeProfit = self.LimitOrder(symbol, -1, price * 1.01)
            self.stopLoss = self.StopMarketOrder(symbol, -1, price * 0.99)
        elif signalDeltaPercent > tolerance:
            # If MACD is significantly above the signal line, go short.
            self.MarketOrder(symbol, -1)
            # Set take profit and stop loss orders.
            self.takeProfit = self.LimitOrder(symbol, 1, price * 0.99)
            self.stopLoss = self.StopMarketOrder(symbol, 1, price * 1.01)
    
    def OnOrderEvent(self, orderEvent):
        """
        Event handler for order events.
        """
        # Only act on filled orders.
        if orderEvent.Status != OrderStatus.Filled:
            return
        # Attempt to cancel the opposite order when one is filled.
        self.Cancel(orderEvent.OrderId)
    
    def Cancel(self, orderId):
        """
        Cancel the opposite pending order when one of the take profit or stop loss orders is filled.
        
        Args:
        orderId: The ID of the filled order to identify the opposite order to cancel.
        """
        # If the filled order is the take profit order, cancel the stop loss.
        if self.takeProfit is not None and orderId == self.takeProfit.OrderId:
            self.stopLoss.Cancel()
        # If the filled order is the stop loss order, cancel the take profit.
        elif self.stopLoss is not None and orderId == self.stopLoss.OrderId:
            self.takeProfit.Cancel()
        
        # Reset the order tickets to None after cancellation.
        self.takeProfit = None
        self.stopLoss = None
from AlgorithmImports import *

class MultiTimeframeTrendStrategy(QCAlgorithm):
    def Initialize(self):
        # Initialize algorithm parameters
        self.SetStartDate(2010, 1, 1)
        # self.SetEndDate(2015, 1, 1)
        self.SetCash(100000)

        # Add SPY Equity with hourly resolution
        spy = self.AddEquity("SPY", Resolution.Hour)
        spy.SetDataNormalizationMode(DataNormalizationMode.Raw)
        self.spySymbol = spy.Symbol

        # Set Benchmark
        self.SetBenchmark("SPY")
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)

        # Initialize opening and previous bar prices for multiple time frames
        self.weeklyOpenPrice = None
        self.dailyOpenPrice = None
        self.hourlyOpenPrice = None
        self.lastDailyHigh = None
        self.lastDailyLow = None
        self.lastHourlyHigh = None
        self.lastHourlyLow = None

        # Schedule functions to update weekly, daily, and hourly opening prices
        self.lastTradeWeek = -1  # Initialize to an invalid week number
        self.Schedule.On(self.DateRules.EveryDay(self.spySymbol), self.TimeRules.AfterMarketOpen(self.spySymbol, 1), self.CheckIfNewWeek)
        self.Schedule.On(self.DateRules.EveryDay(self.spySymbol), self.TimeRules.At(9, 30), self.DailyOpen)

        # Initialize last hour
        self.lastHour = self.Time.hour

    def OnData(self, data):
        # Ensure the algorithm isn't warming up and that SPY data is available.
        if self.IsWarmingUp or self.spySymbol not in data or data[self.spySymbol] is None:
            return

        # Update hourly price data and track high/low for Inside Bar detection.
        if self.Time.hour != self.lastHour:
            if data.Bars.ContainsKey(self.spySymbol):
                bar = data.Bars[self.spySymbol]
                self.hourlyOpenPrice = bar.Open
                self.lastHourlyHigh = bar.High
                self.lastHourlyLow = bar.Low
                self.lastHour = self.Time.hour
                self.insideBarDetected = False  # Reset inside bar detection for the new hour

        # Detect an Inside Bar based on the last hourly high and low.
        if self.lastHourlyHigh is not None and self.lastHourlyLow is not None:
            if self.hourlyOpenPrice < self.lastHourlyHigh and self.hourlyOpenPrice > self.lastHourlyLow:
                self.Debug("Detected an Inside Bar at the hourly time frame")
                self.insideBarDetected = True

        # Ensure all necessary prices are set before proceeding.
        if None in [self.weeklyOpenPrice, self.dailyOpenPrice, self.hourlyOpenPrice]:
            return

        # Current price from the data.
        price = data[self.spySymbol].Price

        # Execute trades based on Inside Bar breakout and trend continuity.
        if self.insideBarDetected:
            # Entry condition for a long position when current price breaks above the Inside Bar's high
            if price > self.lastHourlyHigh and price > self.weeklyOpenPrice and price > self.dailyOpenPrice and price > self.hourlyOpenPrice:
                if not self.Portfolio[self.spySymbol].Invested:
                    self.Log("Inside Bar broken upwards, aligning with TFC for a long position")
                    self.SetHoldings(self.spySymbol, 1)
            # Exit condition if the price breaks below the Inside Bar's low
            elif price < self.lastHourlyLow:
                if self.Portfolio[self.spySymbol].Invested:
                    self.Log("Inside Bar broken downwards, exiting position.")
                    self.Liquidate(self.spySymbol)



    def CheckIfNewWeek(self):
        currentWeek = self.Time.isocalendar()[1]
        if currentWeek != self.lastTradeWeek:
            self.lastTradeWeek = currentWeek
            self.WeeklyOpen()

    def WeeklyOpen(self):
        self.weeklyOpenPrice = self.Securities[self.spySymbol].Price
        self.Log(f"Weekly open price updated on {self.Time.strftime('%Y-%m-%d')}: {self.weeklyOpenPrice}")

    def DailyOpen(self):
        bar = self.Securities[self.spySymbol]
        self.dailyOpenPrice = bar.Price
        self.lastDailyHigh = bar.High
        self.lastDailyLow = bar.Low
        self.Log(f"Daily open price updated on {self.Time.strftime('%Y-%m-%d')}: {self.dailyOpenPrice}")
from AlgorithmImports import *
from QuantConnect.DataSource import *

class USFuturesSecurityMasterDataClassicAlgorithm (QCAlgorithm):
    """
    This algorithm demonstrates the use of the US futures security master to trade a continuous futures contract 
    based on its price relative to a simple moving average (SMA). It goes long when the price is above the SMA 
    by a certain threshold and goes short when the price is below the SMA by the same threshold. The algorithm 
    also handles contract rollovers and logs when these events occur.
    """
    
    threshold = 0.01  # Define a threshold for price deviation from the SMA (1%)
    
    def Initialize(self) -> None:
        """
        Initialize the algorithm settings, add the future contract, and set up the indicators.
        """
        self.SetCash(1000000)  # Set starting cash
        self.SetStartDate(2019, 2, 1)  # Set start date for the backtest
        self.SetEndDate(2021, 6, 1)  # Set end date for the backtest

        # Request continuous future data for Crude Oil WTI with specific data normalization and mapping modes.
        self.continuous_contract = self.AddFuture(Futures.Energies.CrudeOilWTI,
                                                  dataNormalizationMode=DataNormalizationMode.BackwardsRatio,
                                                  dataMappingMode=DataMappingMode.OpenInterest,
                                                  contractDepthOffset=0)
        self.symbol = self.continuous_contract.Symbol  # Get the continuous contract symbol
                      
        # Request historical data to warm up the SMA indicator
        history = self.History(self.symbol, 500, Resolution.Minute)
        self.Debug(f"We got {len(history)} items from our history request")
        
        # Initialize a 10-period SMA indicator with daily resolution
        self.sma = self.SMA(self.symbol, 10, Resolution.Daily)
        # Warm up the SMA with historical data
        if not history.empty:
            for time, row in history.droplevel(0).loc[self.symbol].iterrows():
                self.sma.Update(IndicatorDataPoint(time, row.close))
        

    def OnData(self, slice: Slice) -> None:
        """
        Event handler for new data. Checks for rollover events and trading signals based on the SMA.
        """
        # Check for contract rollover events and handle them
        for symbol, changed_event in slice.SymbolChangedEvents.items():
            old_symbol = changed_event.OldSymbol  # The symbol of the old contract
            new_symbol = changed_event.NewSymbol  # The symbol of the new contract
            tag = f"Rollover - Symbol changed at {self.Time}: {old_symbol} -> {new_symbol}"
            quantity = self.Portfolio[old_symbol].Quantity  # Quantity held of the old contract

            # Liquidate the old contract position and open a new position in the new contract if necessary
            self.Liquidate(old_symbol, tag=tag)
            if quantity != 0: self.MarketOrder(new_symbol, quantity, tag=tag)
            self.Log(tag)
                
        mapped_symbol = self.continuous_contract.Mapped  # The currently mapped contract symbol

        # Check if there is a price update for the continuous contract and the SMA is ready
        if not (slice.Bars.ContainsKey(self.symbol) and self.sma.IsReady and mapped_symbol):
            return
        
        # Trading logic based on the relationship between the current price and the SMA
        current_price = slice.Bars[self.symbol].Price  # The current price of the continuous contract
        sma_value = self.sma.Current.Value  # The current value of the SMA
        # If the current price is significantly above the SMA, and we're not already long, go long
        if current_price > sma_value * (1 + self.threshold) and not self.Portfolio[mapped_symbol].IsLong:
            self.MarketOrder(mapped_symbol, 1)
        # If the current price is significantly below the SMA, and we're not already short, go short
        elif current_price < sma_value * (1 - self.threshold) and not self.Portfolio[mapped_symbol].IsShort:
            self.MarketOrder(mapped_symbol, -1)
from AlgorithmImports import *

class MultiTimeframeTrendStrategy(QCAlgorithm):
    def Initialize(self):
        # Initialize algorithm parameters
        self.SetStartDate(2010, 1, 1)
        # self.SetEndDate(2015, 1, 1)
        self.SetCash(100000)

        # Add SPY Equity with hourly resolution
        spy = self.AddEquity("SPY", Resolution.Hour)
        spy.SetDataNormalizationMode(DataNormalizationMode.Raw)
        self.spySymbol = spy.Symbol

        # Set Benchmark
        self.SetBenchmark("SPY")
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)

        # Initialize opening and previous bar prices for multiple time frames
        self.weeklyOpenPrice = None
        self.dailyOpenPrice = None
        self.hourlyOpenPrice = None
        self.lastDailyHigh = None
        self.lastDailyLow = None
        self.lastHourlyHigh = None
        self.lastHourlyLow = None

        # Schedule functions to update weekly, daily, and hourly opening prices
        self.lastTradeWeek = -1  # Initialize to an invalid week number
        self.Schedule.On(self.DateRules.EveryDay(self.spySymbol), self.TimeRules.AfterMarketOpen(self.spySymbol, 1), self.CheckIfNewWeek)
        self.Schedule.On(self.DateRules.EveryDay(self.spySymbol), self.TimeRules.At(9, 30), self.DailyOpen)

        # Initialize last hour
        self.lastHour = self.Time.hour

    def OnData(self, data):
        # Check for necessary conditions
        if self.IsWarmingUp or self.spySymbol not in data or data[self.spySymbol] is None:
            return

        # Update hourly open and track high/low
        if self.Time.hour != self.lastHour:
            if data.Bars.ContainsKey(self.spySymbol):
                bar = data.Bars[self.spySymbol]
                self.hourlyOpenPrice = bar.Open
                self.lastHourlyHigh = bar.High
                self.lastHourlyLow = bar.Low
                self.lastHour = self.Time.hour
            else:
                self.Debug(f"No hourly open data for {self.spySymbol} at {self.Time}")

        # Check for Inside Bar at the hourly time frame
        if self.hourlyOpenPrice and self.lastHourlyHigh and self.lastHourlyLow:
            if self.hourlyOpenPrice < self.lastHourlyHigh and self.hourlyOpenPrice > self.lastHourlyLow:
                self.Debug("Detected an Inside Bar at the hourly time frame")

        # Ensure all opening prices are set
        if None in [self.weeklyOpenPrice, self.dailyOpenPrice, self.hourlyOpenPrice]:
            return

        # Trading logic based on trend continuity and Inside Bar detection
        price = data[self.spySymbol].Price
        if price > self.weeklyOpenPrice and price > self.dailyOpenPrice and price > self.hourlyOpenPrice:
            if not self.Portfolio[self.spySymbol].Invested:
                self.Log("Timeframes aligned for long position")
                self.SetHoldings(self.spySymbol, 1)  # Long position
        elif price < self.weeklyOpenPrice and price < self.dailyOpenPrice and price < self.hourlyOpenPrice:
            self.Log("Timeframes down, exiting.")
            self.Liquidate(self.spySymbol)  # Exit position

    def CheckIfNewWeek(self):
        currentWeek = self.Time.isocalendar()[1]
        if currentWeek != self.lastTradeWeek:
            self.lastTradeWeek = currentWeek
            self.WeeklyOpen()

    def WeeklyOpen(self):
        self.weeklyOpenPrice = self.Securities[self.spySymbol].Price
        self.Log(f"Weekly open price updated on {self.Time.strftime('%Y-%m-%d')}: {self.weeklyOpenPrice}")

    def DailyOpen(self):
        bar = self.Securities[self.spySymbol]
        self.dailyOpenPrice = bar.Price
        self.lastDailyHigh = bar.High
        self.lastDailyLow = bar.Low
        self.Log(f"Daily open price updated on {self.Time.strftime('%Y-%m-%d')}: {self.dailyOpenPrice}")