Overall Statistics |
Total Trades 8059 Average Win 0.02% Average Loss -0.07% Compounding Annual Return 3.295% Drawdown 49.900% Expectancy 0.072 Net Profit 42.460% Sharpe Ratio 0.275 Loss Rate 20% Win Rate 80% Profit-Loss Ratio 0.34 Alpha 0.105 Beta -3.045 Annual Standard Deviation 0.165 Annual Variance 0.027 Information Ratio 0.156 Tracking Error 0.165 Treynor Ratio -0.015 Total Fees $0.00 |
import pandas as pd from datetime import datetime class AssetClassTrendFollowingAlgorithm(QCAlgorithmFramework): def Initialize(self): self.SetStartDate(2008, 5, 1) self.SetEndDate(datetime.now()) self.SetCash(100000) # Set Strategy Cash self.SetSecurityInitializer(lambda security: security.SetFeeModel(ConstantFeeModel(0))) symbols = [Symbol.Create(ticker, SecurityType.Equity, Market.USA) for ticker in ["SPY", "EFA", "BND", "VNQ", "GSG"]] self.UniverseSettings.Resolution = Resolution.Daily self.SetUniverseSelection( ManualUniverseSelectionModel(symbols) ) self.SetAlpha(AssetClassTrendFollowingAlphaModel(self)) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.SetExecution(ImmediateExecutionModel()) self.SetRiskManagement(NullRiskManagementModel()) class AssetClassTrendFollowingAlphaModel(AlphaModel): '''Alpha model that uses an SMA and security price to create insights''' def __init__(self, algorithm, period = 10*21, resolution = Resolution.Daily): ''' Initializes a new instance of the AssetClassTrendFollowingAlphaModel class Args: algorithm: period: The SMA period resolution: ''' self.period = period self.resolution = resolution self.smaBySymbol = dict() resolutionString = Extensions.GetEnumString(resolution, Resolution) self.Name = f'{self.__class__.__name__}({period},{resolutionString})' self.predictionInterval = Time.Multiply(Extensions.ToTimeSpan(resolution), period) def Update(self, algorithm, data): ''' Updates this alpha model with the latest data from the algorithm. This is called each time the algorithm receives data for subscribed securities Args: algorithm: The algorithm instance data: The new data available Returns: The new insights generated ''' insights = [] for symbol,sma in self.smaBySymbol.items(): if sma.IsReady: if algorithm.Securities[symbol].Price > sma.Current.Value: insights.append(Insight.Price(symbol,self.predictionInterval,InsightDirection.Up)) return insights def OnSecuritiesChanged(self, algorithm, changes): ''' Event fired each time the we add securities from the data feed Args: algorithm: The algorithm instance that experienced the change in securities changes: The security additions and removals from the algorithm ''' addedSymbols = [ x.Symbol for x in changes.AddedSecurities ] history = algorithm.History(addedSymbols, self.period, self.resolution) history = history.close.unstack(level=0) for symbol in addedSymbols: data = self.smaBySymbol.setdefault(symbol, algorithm.SMA(symbol, self.period, self.resolution)) for time, sma in history[str(symbol)].iteritems(): data.Update(time, sma)