Overall Statistics |
Total Trades 4626 Average Win 0.12% Average Loss -0.09% Compounding Annual Return 268.385% Drawdown 14.300% Expectancy 0.207 Net Profit 54.604% Sharpe Ratio 5.528 Probabilistic Sharpe Ratio 92.053% Loss Rate 48% Win Rate 52% Profit-Loss Ratio 1.32 Alpha 2.103 Beta -0.084 Annual Standard Deviation 0.383 Annual Variance 0.146 Information Ratio 3.542 Tracking Error 0.638 Treynor Ratio -25.175 Total Fees $17400.78 |
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.BB1Window.IsReady): continue if not algorithm.Portfolio[sd.Security.Symbol].Invested: if sd.Security.Price>sd.BB1Window[1].Value: 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.BB1Window=RollingWindow[IndicatorDataPoint](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.BB1Window.Add(updated)