Overall Statistics |
Total Trades 313 Average Win 0.01% Average Loss -0.01% Compounding Annual Return 52.949% Drawdown 1.100% Expectancy -0.190 Net Profit 7.736% Sharpe Ratio 6.211 Probabilistic Sharpe Ratio 99.277% Loss Rate 62% Win Rate 38% Profit-Loss Ratio 1.13 Alpha 0.091 Beta 0.983 Annual Standard Deviation 0.075 Annual Variance 0.006 Information Ratio 1.774 Tracking Error 0.048 Treynor Ratio 0.474 Total Fees $319.86 Estimated Strategy Capacity $13000000.00 Lowest Capacity Asset ORCL R735QTJ8XC9X |
from datetime import timedelta from QuantConnect.Data.UniverseSelection import * from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel class SectorBalancedPortfolioConstruction(QCAlgorithm): def Initialize(self): self.SetStartDate(2016, 12, 28) self.SetEndDate(2017, 3, 1) self.SetCash(100000) self.UniverseSettings.Resolution = Resolution.Hour self.SetUniverseSelection(MyUniverseSelectionModel()) self.SetAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(1), 0.025, None)) self.SetPortfolioConstruction(MySectorWeightingPortfolioConstructionModel(Resolution.Daily)) self.SetExecution(ImmediateExecutionModel()) class MyUniverseSelectionModel(FundamentalUniverseSelectionModel): def __init__(self): super().__init__(True, None) def SelectCoarse(self, algorithm, coarse): filtered = [x for x in coarse if x.HasFundamentalData and x.Price > 0] sortedByDollarVolume = sorted(filtered, key=lambda x: x.DollarVolume, reverse=True) return [x.Symbol for x in sortedByDollarVolume][:100] def SelectFine(self, algorithm, fine): filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Technology] self.technology = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:3] filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.FinancialServices] self.financialServices = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:2] filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.ConsumerDefensive] self.consumerDefensive = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1] return [x.Symbol for x in self.technology + self.financialServices + self.consumerDefensive] class MySectorWeightingPortfolioConstructionModel(EqualWeightingPortfolioConstructionModel): def __init__(self, rebalance = Resolution.Daily): super().__init__(rebalance) self.symbolBySectorCode = dict() self.result = dict() def DetermineTargetPercent(self, activeInsights): #1. Set the self.sectorBuyingPower before by dividing one by the length of self.symbolBySectorCode self.sectorBuyingPower = 1/len(self.symbolBySectorCode) for sector, symbols in self.symbolBySectorCode.items(): #2. Search for the active insights in this sector. Save the variable self.insightsInSector self.insightsInSector = [insight for insight in activeInsights if insight.Symbol in symbols] #3. Divide the self.sectorBuyingPower by the length of self.insightsInSector to calculate the variable percent # The percent is the weight we'll assign the direction of the insight self.percent = self.sectorBuyingPower / len(self.insightsInSector) #4. For each insight in self.insightsInSector, assign each insight an allocation. # The allocation is calculated by multiplying the insight direction by the self.percent for insight in self.insightsInSector: self.result[insight] = insight.Direction * self.percent return self.result def OnSecuritiesChanged(self, algorithm, changes): for security in changes.AddedSecurities: sectorCode = security.Fundamentals.AssetClassification.MorningstarSectorCode if sectorCode not in self.symbolBySectorCode: self.symbolBySectorCode[sectorCode] = list() self.symbolBySectorCode[sectorCode].append(security.Symbol) for security in changes.RemovedSecurities: sectorCode = security.Fundamentals.AssetClassification.MorningstarSectorCode if sectorCode in self.symbolBySectorCode: symbol = security.Symbol if symbol in self.symbolBySectorCode[sectorCode]: self.symbolBySectorCode[sectorCode].remove(symbol) super().OnSecuritiesChanged(algorithm, changes)
from AlgorithmImports import * from QuantConnect.Data.Custom.Tiingo import * from datetime import datetime, timedelta import numpy as np class TiingoNewsSentimentAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2016, 11, 1) self.SetEndDate(2017, 3, 1) symbols = [Symbol.Create("AAPL", SecurityType.Equity, Market.USA), Symbol.Create("NKE", SecurityType.Equity, Market.USA)] self.SetUniverseSelection(ManualUniverseSelectionModel(symbols)) self.SetAlpha(NewsSentimentAlphaModel()) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.SetExecution(ImmediateExecutionModel()) self.SetRiskManagement(NullRiskManagementModel()) class NewsData(): def __init__(self, symbol): self.Symbol = symbol self.Window = RollingWindow[float](100) class NewsSentimentAlphaModel(AlphaModel): def __init__(self): self.newsData = {} self.wordScores = { "bad": -0.5, "good": 0.5, "negative": -0.5, "great": 0.5, "growth": 0.5, "fail": -0.5, "failed": -0.5, "success": 0.5, "nailed": 0.5, "beat": 0.5, "missed": -0.5, "profitable": 0.5, "beneficial": 0.5, "right": 0.5, "positive": 0.5, "large":0.5, "attractive": 0.5, "sound": 0.5, "excellent": 0.5, "wrong": -0.5, "unproductive": -0.5, "lose": -0.5, "missing": -0.5, "mishandled": -0.5, "un_lucrative": -0.5, "up": 0.5, "down": -0.5, "unproductive": -0.5, "poor": -0.5, "wrong": -0.5, "worthwhile": 0.5, "lucrative": 0.5, "solid": 0.5 } def Update(self, algorithm, data): insights = [] news = data.Get(TiingoNews) for article in news.Values: words = article.Description.lower().split(" ") score = sum([self.wordScores[word] for word in words if word in self.wordScores]) #1. Get the underlying symbol and save to the variable symbol symbol = article.Symbol.Underlying #2. Add scores to the rolling window associated with its newsData symbol self.newsData[symbol].Window.Add(score) #3. Sum the rolling window scores, save to sentiment # If sentiment aggregate score for the time period is greater than 5, emit an up insight sentiment = sum(self.newsData[symbol].Window) if sentiment > 5: insights.append(Insight.Price(symbol, timedelta(1), InsightDirection.Up)) return insights def OnSecuritiesChanged(self, algorithm, changes): for security in changes.AddedSecurities: symbol = security.Symbol newsAsset = algorithm.AddData(TiingoNews, symbol) self.newsData[symbol] = NewsData(newsAsset.Symbol) for security in changes.RemovedSecurities: newsData = self.newsData.pop(security.Symbol, None) if newsData is not None: algorithm.RemoveSecurity(newsData.Symbol)
from datetime import timedelta from QuantConnect.Data.UniverseSelection import * from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel class SectorBalancedPortfolioConstruction(QCAlgorithm): def Initialize(self): self.SetStartDate(2016, 12, 28) self.SetEndDate(2017, 3, 1) self.SetCash(100000) self.UniverseSettings.Resolution = Resolution.Hour self.SetUniverseSelection(MyUniverseSelectionModel()) self.SetAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(1), 0.025, None)) self.SetPortfolioConstruction(MySectorWeightingPortfolioConstructionModel(Resolution.Daily)) self.SetExecution(ImmediateExecutionModel()) class MyUniverseSelectionModel(FundamentalUniverseSelectionModel): def __init__(self): super().__init__(True, None) def SelectCoarse(self, algorithm, coarse): filtered = [x for x in coarse if x.HasFundamentalData and x.Price > 0] sortedByDollarVolume = sorted(filtered, key=lambda x: x.DollarVolume, reverse=True) return [x.Symbol for x in sortedByDollarVolume][:100] def SelectFine(self, algorithm, fine): filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Technology] self.technology = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:3] filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.FinancialServices] self.financialServices = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:2] filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.ConsumerDefensive] self.consumerDefensive = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:1] return [x.Symbol for x in self.technology + self.financialServices + self.consumerDefensive] class MySectorWeightingPortfolioConstructionModel(EqualWeightingPortfolioConstructionModel): def __init__(self, rebalance = Resolution.Daily): super().__init__(rebalance) self.symbolBySectorCode = dict() self.result = dict() def DetermineTargetPercent(self, activeInsights): #1. Set the self.sectorBuyingPower before by dividing one by the length of self.symbolBySectorCode self.sectorBuyingPower = 1/len(self.symbolBySectorCode) for sector, symbols in self.symbolBySectorCode.items(): #2. Search for the active insights in this sector. Save the variable self.insightsInSector self.insightsInSector = [insight for insight in activeInsights if insight.Symbol in symbols] #3. Divide the self.sectorBuyingPower by the length of self.insightsInSector to calculate the variable percent # The percent is the weight we'll assign the direction of the insight self.percent = self.sectorBuyingPower / len(self.insightsInSector) #4. For each insight in self.insightsInSector, assign each insight an allocation. # The allocation is calculated by multiplying the insight direction by the self.percent for insight in self.insightsInSector: self.result[insight] = insight.Direction * self.percent return self.result def OnSecuritiesChanged(self, algorithm, changes): for security in changes.AddedSecurities: sectorCode = security.Fundamentals.AssetClassification.MorningstarSectorCode if sectorCode not in self.symbolBySectorCode: self.symbolBySectorCode[sectorCode] = list() self.symbolBySectorCode[sectorCode].append(security.Symbol) for security in changes.RemovedSecurities: sectorCode = security.Fundamentals.AssetClassification.MorningstarSectorCode if sectorCode in self.symbolBySectorCode: symbol = security.Symbol if symbol in self.symbolBySectorCode[sectorCode]: self.symbolBySectorCode[sectorCode].remove(symbol) super().OnSecuritiesChanged(algorithm, changes)
from datetime import timedelta from AlgorithmImports import * """ [The QC Algorithm Framework is the foundation for building a robust and flexible investment strategy. The framework architecture makes it simple to reuse code and provides the scaffolding for good algorithm design.] * Universe Selection Model * Alpha Model * Portfolio Construction Model * Execution model """ class SMAPairsTrading(QCAlgorithm): def Initialize(self): self.SetStartDate(2018, 7, 1) self.SetEndDate(2019, 3, 31) self.SetCash(100000) symbols = [Symbol.Create("PEP", SecurityType.Equity, Market.USA), Symbol.Create("KO", SecurityType.Equity, Market.USA)] self.AddUniverseSelection(ManualUniverseSelectionModel(symbols)) self.UniverseSettings.Resolution = Resolution.Hour self.UniverseSettings.DataNormalizationMode = DataNormalizationMode.Raw self.AddAlpha(PairsTradingAlphaModel()) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.SetExecution(ImmediateExecutionModel()) def OnEndOfDay(self, symbol): self.Log("Taking a position of " + str(self.Portfolio[symbol].Quantity) + " units of symbol " + str(symbol)) class PairsTradingAlphaModel(AlphaModel): def __init__(self): self.pair = [ ] self.spreadMean = SimpleMovingAverage(500) self.spreadStd = StandardDeviation(500) self.period = timedelta(hours=2) def Update(self, algorithm, data): spread = self.pair[1].Price - self.pair[0].Price self.spreadMean.Update(algorithm.Time, spread) self.spreadStd.Update(algorithm.Time, spread) upperthreshold = self.spreadMean.Current.Value + self.spreadStd.Current.Value lowerthreshold = self.spreadMean.Current.Value - self.spreadStd.Current.Value if spread > upperthreshold: return Insight.Group( [ Insight.Price(self.pair[0].Symbol, self.period, InsightDirection.Up), Insight.Price(self.pair[1].Symbol, self.period, InsightDirection.Down) ]) if spread < lowerthreshold: return Insight.Group( [ Insight.Price(self.pair[0].Symbol, self.period, InsightDirection.Down), Insight.Price(self.pair[1].Symbol, self.period, InsightDirection.Up) ]) return [] def OnSecuritiesChanged(self, algorithm, changes): self.pair = [x for x in changes.AddedSecurities] #1. Call for 500 bars of history data for each symbol in the pair and save to the variable history history = algorithm.History([x.Symbol for x in self.pair], 500) #2. Unstack the Pandas data frame to reduce it to the history close price history = history.close.unstack(level=0) #3. Iterate through the history tuple and update the mean and standard deviation with historical data for tuple in history.itertuples(): self.spreadMean.Update(tuple[0], tuple[2]-tuple[1]) self.spreadStd.Update(tuple[0], tuple[2]-tuple[1])
from datetime import timedelta from AlgorithmImports import * """ [The QC Algorithm Framework is the foundation for building a robust and flexible investment strategy. The framework architecture makes it simple to reuse code and provides the scaffolding for good algorithm design.] * Universe Selection Model * Alpha Model * Portfolio Construction Model * Execution model """ class MOMAlphaModel(AlphaModel): def __init__(self): self.mom = [] def OnSecuritiesChanged(self, algorithm, changes): for security in changes.AddedSecurities: symbol = security.Symbol self.mom.append({"symbol":symbol, "indicator":algorithm.MOM(symbol, 14, Resolution.Daily)}) def Update(self, algorithm, data): ordered = sorted(self.mom, key=lambda kv: kv["indicator"].Current.Value, reverse=True) return Insight.Group([Insight.Price(ordered[0]['symbol'], timedelta(1), InsightDirection.Up), Insight.Price(ordered[1]['symbol'], timedelta(1), InsightDirection.Flat) ]) class FrameworkAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2013, 10, 1) self.SetEndDate(2013, 12, 1) self.SetCash(100000) symbols = [Symbol.Create("SPY", SecurityType.Equity, Market.USA), Symbol.Create("BND", SecurityType.Equity, Market.USA) ] self.UniverseSettings.Resolution = Resolution.Daily self.SetUniverseSelection(ManualUniverseSelectionModel(symbols)) self.SetAlpha(MOMAlphaModel()) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.SetRiskManagement(MaximumDrawdownPercentPerSecurity(0.02)) self.SetExecution(ImmediateExecutionModel())
from AlgorithmImports import * class EMAMomentumUniverse(QCAlgorithm): def Initialize(self): self.SetStartDate(2019, 1, 7) self.SetEndDate(2019, 4, 1) self.SetCash(100000) self.UniverseSettings.Resolution = Resolution.Daily self.AddUniverse(self.CoarseSelectionFunction) self.averages = { } def CoarseSelectionFunction(self, universe): selected = [] universe = sorted(universe, key=lambda c: c.DollarVolume, reverse=True) universe = [c for c in universe if c.Price > 10][:100] for coarse in universe: symbol = coarse.Symbol if symbol not in self.averages: # 1. Call history to get an array of 200 days of history data history = self.History(symbol, 200, Resolution.Daily) #2. Adjust SelectionData to pass in the history result self.averages[symbol] = SelectionData(history) self.averages[symbol].update(self.Time, coarse.AdjustedPrice) if self.averages[symbol].is_ready() and self.averages[symbol].fast > self.averages[symbol].slow: selected.append(symbol) return selected[:10] def OnSecuritiesChanged(self, changes): for security in changes.RemovedSecurities: self.Liquidate(security.Symbol) for security in changes.AddedSecurities: self.SetHoldings(security.Symbol, 0.10) class SelectionData(): #3. Update the constructor to accept a history array def __init__(self, history): self.slow = ExponentialMovingAverage(200) self.fast = ExponentialMovingAverage(50) #4. Loop over the history data and update the indicators for bar in history.itertuples(): self.fast.Update(bar.Index[1], bar.close) self.slow.Update(bar.Index[1], bar.close) def is_ready(self): return self.slow.IsReady and self.fast.IsReady def update(self, time, price): self.fast.Update(time, price) self.slow.Update(time, price)
from AlgorithmImports import * """" Buy and Hold with a Trailing Stop Setting up a Stop Market Order """ class BootCampTask(QCAlgorithm): def Initialize(self): self.SetStartDate(2018, 12, 1) # Set Start Date self.SetEndDate(2019, 4, 1) # Set End Date self.SetCash(100000) # Set Strategy Cash #1. Subscribe to SPY in raw mode spy = self.AddEquity("SPY", Resolution.Daily) spy.SetDataNormalizationMode(DataNormalizationMode.Raw) def OnData(self, data): if not self.Portfolio.Invested: #2. Create market order to buy 500 units of SPY self.MarketOrder("SPY", 500) #3. Create a stop market order to sell 500 units at 90% of the SPY current price self.StopMarketOrder("SPY", -500, 0.90*self.Securities["SPY"].Close)
from AlgorithmImports import * from datetime import timedelta from QuantConnect.Data.UniverseSelection import * from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel class LiquidValueStocks(QCAlgorithm): def Initialize(self): self.SetStartDate(2017, 5, 15) self.SetEndDate(2017, 7, 15) self.SetCash(100000) self.UniverseSettings.Resolution = Resolution.Hour self.AddUniverseSelection(LiquidValueUniverseSelectionModel()) self.AddAlpha(LongShortEYAlphaModel()) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.SetRiskManagement(MaximumDrawdownPercentPerSecurity(0.02)) self.SetExecution(ImmediateExecutionModel()) class LiquidValueUniverseSelectionModel(FundamentalUniverseSelectionModel): def __init__(self): super().__init__(True, None) self.lastMonth = -1 def SelectCoarse(self, algorithm, coarse): if self.lastMonth == algorithm.Time.month: return Universe.Unchanged self.lastMonth = algorithm.Time.month sortedByDollarVolume = sorted([x for x in coarse if x.HasFundamentalData], key=lambda x: x.DollarVolume, reverse=True) return [x.Symbol for x in sortedByDollarVolume[:100]] def SelectFine(self, algorithm, fine): sortedByYields = sorted(fine, key=lambda f: f.ValuationRatios.EarningYield, reverse=True) universe = sortedByYields[:10] + sortedByYields[-10:] return [f.Symbol for f in universe] # Define the LongShortAlphaModel class class LongShortEYAlphaModel(AlphaModel): def __init__(self): self.lastMonth = -1 def Update(self, algorithm, data): insights = [] if self.lastMonth == algorithm.Time.month: return insights self.lastMonth = algorithm.Time.month # For loop to emit insights with insight directions # based on whether earnings yield is greater or less than zero once a month for security in algorithm.ActiveSecurities.Values: direction = 1 if security.Fundamentals.ValuationRatios.EarningYield > 0 else -1 insights.append(Insight.Price(security.Symbol, timedelta(28), direction)) return insights
from datetime import timedelta from AlgorithmImports import * class P03(QCAlgorithm): '''' [Opening Range Breakout] Opening range breakout uses a defined period of time to set a price-range, and trades on leaving that range. To achieve this we will start by consolidating the first 30 minutes of data. Close < Bar(30m).low, SHORT Close > Bar(30m).high, LOONG Liquidate @ 13:30 ''' openingBar = None def Initialize(self): self.SetStartDate(2018, 7, 10) # Set Start Date self.SetEndDate(2019, 6, 30) # Set End Date self.SetCash(100000) # Set Strategy Cash # Subscribe to TSLA with Minute Resolution self.AddEquity("TSLA", Resolution.Minute) # Create our consolidator with a timedelta of 30 min self.Consolidate("TSLA", timedelta(minutes=30), self.OnDataConsolidated) # Create a scheduled event triggered at 13:30 calling the ClosePositions function self.Schedule.On(self.DateRules.EveryDay("TSLA"), self.TimeRules.At(13,30), self.ClosePositions) def OnData(self, data): if self.Portfolio.Invested or self.openingBar==None: pass else: if data["TSLA"].Close < self.openingBar.Low: self.SetHoldings("TSLA", -1) if data["TSLA"].Close > self.openingBar.High: self.SetHoldings("TSLA", 1) #2. Create a function OnDataConsolidator which saves the currentBar as bar def OnDataConsolidated(self, bar): # Check the time, we only want to work with the first 30min after Market Open # Save one bar as openingBar if bar.Time.hour == 9 and bar.Time.minute == 30: self.openingBar = bar def ClosePositions(self): self.openingBar = None self.Liquidate("TSLA")
from datetime import datetime from AlgorithmImports import * class P01(QCAlgorithm): # Order ticket for our stop order, Datetime when stop order was last hit stopMarketTicket = None stopMarketOrderFillTime = datetime.min highestSPYPrice = 0 def Initialize(self): self.SetStartDate(2010, 12, 1) self.SetEndDate(2020, 12, 10) self.SetCash(100000) spy = self.AddEquity("SPY", Resolution.Daily) spy.SetDataNormalizationMode(DataNormalizationMode.Raw) def OnData(self, data): # self.Log(self.Securities["SPY"].Close) # Plot the current SPY price to "Data Chart" on series "Asset Price" self.Plot("Data Chart", "Asset Price", data["SPY"].Close) # at least hold for 15 days if (self.Time - self.stopMarketOrderFillTime).days < 15: return if not self.Portfolio.Invested: self.MarketOrder("SPY", 500) # 当市场价格下降到【买入价格】的90%时,以市场价格卖出 self.stopMarketTicket = self.StopMarketOrder("SPY", -500, round(0.9 * self.Securities["SPY"].Close, 2)) else: # Plot the moving stop price on "Data Chart" with "Stop Price" series name self.Plot("Data Chart", "Stop Price", self.stopMarketTicket.Get(OrderField.StopPrice)) # Check if the SPY price is higher that highestSPYPrice. if self.Securities["SPY"].Close > self.highestSPYPrice: #2. Save the new high to highestSPYPrice; then update the stop price to 90% of highestSPYPrice self.highestSPYPrice = self.Securities["SPY"].Close updateFields = UpdateOrderFields() updateFields.StopPrice = round(self.highestSPYPrice * 0.9, 2) self.stopMarketTicket.Update(updateFields) #3. Print the new stop price with Debug() self.Debug("SPY: " + str(self.highestSPYPrice) + " Stop: " + str(updateFields.StopPrice)) def OnOrderEvent(self, orderEvent): if orderEvent.Status != OrderStatus.Filled: return if self.stopMarketTicket is not None and self.stopMarketTicket.OrderId == orderEvent.OrderId: self.stopMarketOrderFillTime = self.Time
from AlgorithmImports import * '''' [Setting Up a Coarse Universe Filter] 1. Sort descending by daily dollar volume 2. Select only Symbols with a price of more than $10 per share 3. Return the 8 most liquid Symbols from the filteredByPrice list ''' class P04(QCAlgorithm): filteredByPrice = None def Initialize(self): self.SetStartDate(2019, 1, 11) self.SetEndDate(2019, 7, 1) self.SetCash(100000) # Add a Universe model using Coarse Fundamental Data and set the filter function self.AddUniverse(self.CoarseSelectionFilter) self.UniverseSettings.Resolution = Resolution.Daily self.UniverseSettings.Leverage = 2 def CoarseSelectionFilter(self, coarse): # Sort descending by daily dollar volume sortedByDollarVolume = sorted(coarse, key=lambda c: c.DollarVolume, reverse=True) # Select only Symbols with a price of more than $10 per share self.filteredByPrice = [c.Symbol for c in sortedByDollarVolume if c.Price > 10] # Return the 8 most liquid Symbols from the filteredByPrice list self.filteredByPrice = self.filteredByPrice[:8] return self.filteredByPrice # Monitoring Universe Changes def OnSecuritiesChanged(self, changes): # Save securities changed as self.changes self.changes = changes # Log the changes in the function self.Log(f"OnSecuritiesChanged({self.Time}):: {changes}") # Liquidate removed securities for security in changes.RemovedSecurities: if security.Invested: self.Liquidate(security.Symbol) # We want 10% allocation in each security in our universe for security in changes.AddedSecurities: self.SetHoldings(security.Symbol, 0.1)
from AlgorithmImports import * """" Fading The Gap The difference between the close price of the previous day and the opening price of the current day is referred to as a gap. Fading the gap is a strategy that monitors for a large gap down and buys stock assuming it will rebound. """ class FadingTheGap(QCAlgorithm): def Initialize(self): self.SetStartDate(2017, 1, 1) self.SetEndDate(2021, 7, 1) self.SetCash(100000) self.tsla = self.AddEquity ("TSLA", Resolution.Minute).Symbol # Create a scheduled event to run every day at "0 minutes" before # TSLA market close that calls the method ClosingBar self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.BeforeMarketClose(self.tsla, 0), self.ClosingBar) # Create a scheduled event to run every day at 1 minute after # TSLA market open that calls the method OpeningBar self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen(self.tsla, 1), self.OpeningBar) # Create a scheduled event to run every day at 45 minutes after # TSLA market open that calls the method ClosePositions self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen(self.tsla, 45), self.ClosePositions) # Save a RollingWindow with type TradeBar and length of 2 as self.window self.window = RollingWindow[TradeBar](2) # calculating TSLA volatility for a 60 minutes self.volatility = StandardDeviation(self.tsla, 60) def ClosingBar(self): self.window.Add(self.CurrentSlice[self.tsla]) def OpeningBar(self): if "TSLA"in self.CurrentSlice.Bars: self.window.Add(self.CurrentSlice[self.tsla]) if not self.window.IsReady or not self.volatility.IsReady: return # Calculate the change in over night price delta = self.window[0].Value - self.window[1].Value self.deviations = delta / self.volatility.Current.Value # SetHoldings() to 100% TSLA if deviations is less than -3 standard deviations (i.e. when we are 99% confident this gap is an anomaly). if self.deviations < -3 : self.SetHoldings(self.tsla, 1) self.Debug("Open: " + str(self.window[0].Value) + "LastClose: " + str(self.window[1].Value)) # Liquidate our position to limit our exposure and keep our holding period short def ClosePositions(self): self.Liquidate() def OnData(self, data): # self.Debug("Call Event: " + str(self.CurrentSlice[self.tsla].Price)) if data[self.tsla] is not None: self.volatility.Update(self.Time, data[self.tsla].Close)
from AlgorithmImports import * '''' [Momentum-Based Tactical Allocation] Momentum Percentage Indicator: computes the n-period percent change in the security If SPY has more upward momentum than BND, then we liquidate our holdings in BND and allocate 100% of our equity to SPY ''' class P02(QCAlgorithm): def Initialize(self): self.SetStartDate(2007, 8, 1) # Set Start Date self.SetEndDate(2010, 8, 1) # Set End Date #1. Subscribe to SPY -- S&P 500 Index ETF -- using daily resolution self.spy = self.AddEquity("SPY", Resolution.Daily) #2. Subscribe to BND -- Vanguard Total Bond Market ETF -- using daily resolution self.bnd = self.AddEquity("BND", Resolution.Daily) #3. Set strategy cash to $3000 self.SetCash(3000) # Add 50-day Momentum Percent indicator: # Momentum Percentage Indicator: computes the n-period percent change in the security self.spyMomentum = self.MOMP("SPY", 50, Resolution.Daily) self.bondMomentum = self.MOMP("BND", 50, Resolution.Daily) # Set Benchmark self.SetBenchmark("SPY") self.SetWarmUp(50) def OnData(self, data): if self.IsWarmingUp: return if not self.Time.weekday() == 1: return # If SPY has more upward momentum than BND, then we liquidate our holdings in BND and allocate 100% of our equity to SPY if self.spyMomentum.Current.Value > self.bondMomentum.Current.Value: self.Liquidate("BND") self.SetHoldings("SPY", 1) # Allocate 100% to SPY else: self.Liquidate("SPY") self.SetHoldings("BND", 1)