Overall Statistics |
Total Trades 4 Average Win 0.62% Average Loss 0% Compounding Annual Return 12.044% Drawdown 0.900% Expectancy 0 Net Profit 1.244% Sharpe Ratio 4.467 Probabilistic Sharpe Ratio 95.355% Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha 0.087 Beta 0.039 Annual Standard Deviation 0.025 Annual Variance 0.001 Information Ratio -3.882 Tracking Error 0.145 Treynor Ratio 2.894 Total Fees $5.99 Estimated Strategy Capacity $95000000.00 |
from clr import AddReference AddReference("System") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Algorithm.Framework") AddReference("QuantConnect.Common") from QuantConnect import * from QuantConnect.Parameters import * from QuantConnect.Benchmarks import * from QuantConnect.Brokerages import * from QuantConnect.Util import * from QuantConnect.Interfaces import * from QuantConnect.Algorithm import * from QuantConnect.Algorithm.Framework import * from QuantConnect.Algorithm.Framework.Selection import * from QuantConnect.Algorithm.Framework.Alphas import * from QuantConnect.Algorithm.Framework.Portfolio import * from QuantConnect.Algorithm.Framework.Execution import * from QuantConnect.Algorithm.Framework.Risk import * from QuantConnect.Indicators import * from QuantConnect.Data import * from QuantConnect.Data.Consolidators import * from QuantConnect.Data.Custom import * from QuantConnect.Data.Fundamental import * from QuantConnect.Data.Market import * from QuantConnect.Data.UniverseSelection import * from QuantConnect.Notifications import * from QuantConnect.Orders import * from QuantConnect.Orders.Fees import * from QuantConnect.Orders.Fills import * from QuantConnect.Orders.Slippage import * from QuantConnect.Scheduling import * from QuantConnect.Securities import * from QuantConnect.Securities.Equity import * from QuantConnect.Securities.Forex import * from QuantConnect.Securities.Interfaces import * from datetime import date, datetime, timedelta from QuantConnect.Python import * from QuantConnect.Storage import * QCAlgorithmFramework = QCAlgorithm QCAlgorithmFrameworkBridge = QCAlgorithm import calendar class FirstDaySPY(QCAlgorithmFramework): """Buy on close on the last day of the month and sell on the close of the next day""" def Initialize(self): #self.SetStartDate(2020, 1, 28) # Set Start Date self.SetStartDate(2020, 7, 27) self.SetEndDate(2020, 9, 5) self.SetCash(100000) # Set Strategy Cash # Parameters self.maximumDuration = 1 # maximum duration to keep trades open # Universe self.UniverseSettings.Resolution = Resolution.Hour # symbols = [ Symbol.Create("SPY", SecurityType.Equity, Market.USA) ] self.AddEquity("SPY", Resolution.Hour) # self.AddUniverseSelection( ManualUniverseSelectionModel(symbols) ) # self.AddUniverseSelection(CoarseFundamentalUniverseSelectionModel(self.SelectCoarse)) self.AddAlpha(FirstDayAlphaModel()) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel(lambda time: None)) #self.AddRiskManagement(FixedDurationTrades(self.maximumDuration)) # TODO: verify this, I want to buy on close at the end of the last day and sell on close of the next day self.SetExecution(ImmediateExecutionModel()) def SelectCoarse(self, coarse): #self.Debug(f"In universe selection time: {self.Time}") # TODO: smooth that sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True) isETF = [x.Symbol for x in sortedByDollarVolume if not x.HasFundamentalData] #self.Debug(f"Total coarse stocks: {len(sortedByDollarVolume)} and total nonFundamental: {len(isETF)}") return isETF[:10] def OnSecuritiesChanged(self, changes): self._changes = changes #self.Debug(f"OnSecuritiesChanged({self.UtcTime}):: {changes}") #self.Log(f"OnSecuritiesChanged({self.UtcTime}):: {changes}") # def OnData(self, data): # """OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. # Arguments: # data: Slice object keyed by symbol containing the stock data # """ # # if not self.Portfolio.Invested: # # self.SetHoldings("SPY", 1) # # self.Debug("Purchased Stock") class FixedDurationTrades(RiskManagementModel): def __init__(self, maximumDuration = 1): """Provides an implementation of IRiskManagementModel that limits the maximum number of periods that we can stay in a trade""" self.maximumDuration = maximumDuration self.investedTime = {} def ManageRisk(self, algorithm, targets): riskAdjustedTargets = list() for kvp in algorithm.Securities: symbol = kvp.Key security = kvp.Value # Remove if not invested if not security.Invested: self.investedTime.pop(symbol, None) continue # Add newly invested securities if symbol not in self.investedTime: self.investedTime[symbol] = 0 # Set to 0 periods invested continue self.investedTime[symbol] += 1 if self.investedTime[symbol] >= self.maximumDuration: # liquidate securities that have reached max duration riskAdjustedTargets.append(PortfolioTarget(symbol, 0.)) #algorithm.Debug(f"Setting liquidation target for {symbol}") return riskAdjustedTargets class FirstDayAlphaModel(AlphaModel): Name = "FirstDayAlphaModel" def Update(self, algorithm, slice): # Updates this alpha model with the latest data from the algorithm. # This is called each time the algorithm receives data for subscribed securities # Generate insights on the securities in the universe. insights = [] #algorithm.Debug(f"Inside Alpha Model at time: {algorithm.Time}") symbols = list(algorithm.ActiveSecurities.Keys) #algorithm.Debug(f"Active symbols: {[s.Value for s in symbols]}") # insight expiry time and direction insightExpiry = Expiry.EndOfDay(algorithm.Time) insightDirection = InsightDirection.Up # insight direction # TODO: weight by how many often this worked in the past for symbol in symbols: next_market_open = algorithm.Securities[symbol].Exchange.Hours.GetNextMarketOpen(slice.Time, False) last_trading_day = next_market_open.month != slice.Time.month # add insights if it's the last tradable day of the month if last_trading_day and not algorithm.Portfolio.Invested: algorithm.Debug(f"Last Day of the month ({algorithm.Time}), Emit insight for symbol {symbol.Value}") #algorithm.Debug(f"at {algorithm.Time}: {list(algorithm.DateRules.MonthEnd(symbol, 0).GetDates(algorithm.Time, algorithm.Time)) }") insights.append(Insight.Price(symbol, insightExpiry, insightDirection, None, None, None, None)) return insights def OnSecuritiesChanged(self, algorithm, changes): # Handle security changes in from your universe model. pass