| 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)