| Overall Statistics |
|
Total Trades 1130 Average Win 1.41% Average Loss -1.31% Compounding Annual Return 5.320% Drawdown 46.700% Expectancy 0.106 Net Profit 89.362% Sharpe Ratio 0.376 Loss Rate 47% Win Rate 53% Profit-Loss Ratio 1.08 Alpha 0.143 Beta -5.54 Annual Standard Deviation 0.139 Annual Variance 0.019 Information Ratio 0.258 Tracking Error 0.139 Treynor Ratio -0.009 Total Fees $4070.34 |
from Execution.ImmediateExecutionModel import ImmediateExecutionModel
from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel
class HorizontalMultidimensionalReplicator(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2007, 1, 1) # Set Start Date
self.SetCash(100000) # Set Strategy Cash
self.AddAlpha(PanicToExcuberanceAlphaModel(self))
self.SetExecution(ImmediateExecutionModel())
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
symbols = [ Symbol.Create("SPY", SecurityType.Equity, Market.USA) ]
self.SetUniverseSelection( ManualUniverseSelectionModel(symbols) )
class PanicToExcuberanceAlphaModel(AlphaModel):
# This Alpha uses data from URC that contains the number of companies currently reaching new highs
# in stock price, within the NASDAQ exchange. It is likely that very few companies are reaching
# new highs when a recession is imminent. Many companies reach new highs when market participants
# are exuberant.
# This Alpha Model uses smoothed Exponential Moving Average (EMA) to determine how many companies
# on average are reaching a new high. If the number of companies is less than 50, then it emits
# insights and continues to do so until the number of companies is greater than 100.
## More URC market data can be found at Quandl
## https://www.quandl.com/data/URC-Unicorn-Research-Corporation
def __init__(self, algorithm):
# Add Quandl data
self.yearlyHighs = algorithm.AddData(QuandlData, 'URC/NASDAQ_52W_HI',Resolution.Daily).Symbol
# Set predicition period
self.period = timedelta(days=1)
# Set lookback window for Rolling Window and EMA Indicator
self.lookback = 5
# Set resolution for EMA Indicator
self.resolution = Resolution.Daily
self.emitInsights = False
self.cnt = 0
def Update(self, algorithm, data):
insights = []
# Return if no data
if not data.ContainsKey(self.yearlyHighs): return insights
# Set emitInsights to false when the number of companies greater than 250
if self.emaWin[0].Value > 150:
self.emitInsights = False
self.cnt = self.cnt+1
# Set emitInsights to false when the number of companies is less than 5
elif self.emaWin[0].Value < 50:
self.emitInsights = True
algorithm.Log(self.cnt)
# Emit insights
if self.emitInsights:
insights.append(Insight.Price("SPY", self.period, InsightDirection.Up, 0.001))
return insights
def OnSecuritiesChanged(self,algorithm,changes):
for added in changes.AddedSecurities:
# Only add EMA and Rolling Window for custom data
if added.Symbol == self.yearlyHighs:
# Construct an EMA indicator and a rolling window for added securities
algorithm.EMA(added.Symbol, self.lookback,self.resolution).Updated += self.emaUpdated
self.emaWin = RollingWindow[IndicatorDataPoint](self.lookback)
# Adds values to rolling window
def emaUpdated(self, sender, updated):
self.emaWin.Add(updated)
class QuandlData(PythonQuandl):
def __init__(self):
## Retrieve the data from the the Quandl object, specifying the data field used on Quandl
self.ValueColumnName = "NUMBERS OF STOCKS"