| Overall Statistics |
|
Total Trades 675 Average Win 1.39% Average Loss -0.95% Compounding Annual Return 7.162% Drawdown 22.500% Expectancy 0.260 Net Profit 117.868% Sharpe Ratio 0.662 Loss Rate 49% Win Rate 51% Profit-Loss Ratio 1.47 Alpha 0.097 Beta -2.172 Annual Standard Deviation 0.092 Annual Variance 0.009 Information Ratio 0.484 Tracking Error 0.092 Treynor Ratio -0.028 Total Fees $3891.73 |
from Execution.ImmediateExecutionModel import ImmediateExecutionModel
from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel
class HorizontalMultidimensionalReplicator(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2008, 1, 23) # 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 5, then it emits
# insights until the number of companies reaches 200.
## 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 = 50
# Set resolution for EMA Indicator
self.resolution = Resolution.Daily
self.emitInsights = False
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 > 200:
self.emitInsights = False
# Set emitInsights to false when the number of companies is less than 5
elif self.emaWin[0].Value < 5:
self.emitInsights = True
# 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"