Overall Statistics |
Total Trades 974 Average Win 0.64% Average Loss -0.57% Compounding Annual Return 151.398% Drawdown 60.100% Expectancy 0.155 Net Profit 36.074% Sharpe Ratio 2.465 Probabilistic Sharpe Ratio 54.704% Loss Rate 46% Win Rate 54% Profit-Loss Ratio 1.13 Alpha 2.933 Beta 0.551 Annual Standard Deviation 1.158 Annual Variance 1.34 Information Ratio 2.612 Tracking Error 1.148 Treynor Ratio 5.176 Total Fees $14665.89 |
from datetime import datetime,timedelta import numpy as np class EMAUniverse(QCAlgorithm): def Initialize(self): self.SetStartDate(2020,1,22) #Set Start Date self.SetEndDate(2020,5,22) #Set End Date self.SetCash(1000000) #Set Strategy Cash self.SetBrokerageModel(AlphaStreamsBrokerageModel()) self.UniverseSettings.Resolution = Resolution.Daily self.SetBenchmark(self.AddEquity('SPY', Resolution.Daily).Symbol) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.AddAlpha(BBAlpha()) self.SetUniverseSelection(LiquidETFUniverse()) self.SetExecution(ImmediateExecutionModel()) self.coarse_count = 1 self.averages = { }; class BBAlpha(AlphaModel): def __init__(self, fastPeriod = 12, slowPeriod = 26, signalPeriod = 9, movingAverageType = MovingAverageType.Simple, resolution = Resolution.Daily): self.fastPeriod = fastPeriod self.slowPeriod = slowPeriod self.signalPeriod = signalPeriod self.movingAverageType = movingAverageType self.resolution = resolution self.symbolData2 = {} resolutionString = Extensions.GetEnumString(resolution, Resolution) movingAverageTypeString = Extensions.GetEnumString(movingAverageType, MovingAverageType) self.Name = '{}({},{},{},{},{})'.format(self.__class__.__name__, fastPeriod, slowPeriod, signalPeriod, movingAverageTypeString, resolutionString) self.month = None self.finalupperband=None self.direction = InsightDirection.Flat def Update(self, algorithm, data): insights = [] for key, sd in self.symbolData2.items(): self.symbol=sd.Security.Symbol if sd.Security.Price == 0: continue if not (sd.BB1UpperWindow.IsReady): continue if not algorithm.Portfolio[sd.Security.Symbol].Invested: if sd.Security.Price>sd.BB1UpperWindow[1]: self.month = algorithm.Time.month insight = Insight.Price(sd.Security.Symbol, timedelta(hours = 25), InsightDirection.Up, None,None,None,1) self.direction = InsightDirection.Up insights.append(insight) sd.PreviousDirection = insight.Direction return insights def OnSecuritiesChanged(self, algorithm, changes): for added in changes.AddedSecurities: self.symbol=added.Symbol self.symbolData2[added.Symbol] = SymbolData2(algorithm, added, self.fastPeriod, self.slowPeriod, self.signalPeriod, self.movingAverageType, self.resolution) for removed in changes.RemovedSecurities: data = self.symbolData2.pop(removed.Symbol, None) if data is not None: algorithm.SubscriptionManager.RemoveConsolidator(removed.Symbol, data.Consolidator) class SymbolData2(object): def __init__(self, algorithm, security, fastPeriod, slowPeriod, signalPeriod, movingAverageType, resolution): self.Security = security self.Consolidator = algorithm.ResolveConsolidator(security.Symbol, resolution) self.BB1 = BollingerBands(20, 2) algorithm.RegisterIndicator(security.Symbol, self.BB1, self.Consolidator) self.BB1.Updated+=self.BB1Updated self.BB1UpperWindow=RollingWindow[float](20) self.BB1LowerWindow=RollingWindow[float](20) self.PreviousDirection = None #try: history = algorithm.History(security.Symbol, 50, Resolution.Daily) self.WarmUpIndicators2(history) #except KeyError: # pass def WarmUpIndicators2(self, history): for index, row in history.loc[str(self.Security.Symbol)].iterrows(): self.BB1.Update(index,row["close"]) def BB1Updated(self, sender, updated): self.BB1UpperWindow.Add(sender.UpperBand.Current.Value) self.BB1LowerWindow.Add(sender.LowerBand.Current.Value)