| Overall Statistics |
|
Total Trades 8784 Average Win 0.02% Average Loss -0.05% Compounding Annual Return 2.582% Drawdown 50.400% Expectancy 0.071 Net Profit 35.478% Sharpe Ratio 0.234 Loss Rate 29% Win Rate 71% Profit-Loss Ratio 0.51 Alpha 0.109 Beta -3.593 Annual Standard Deviation 0.165 Annual Variance 0.027 Information Ratio 0.115 Tracking Error 0.165 Treynor Ratio -0.011 Total Fees $8809.58 |
from clr import AddReference
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Algorithm.Framework")
AddReference("QuantConnect.Indicators")
from QuantConnect import *
from QuantConnect.Indicators import *
from QuantConnect.Algorithm import *
from QuantConnect.Algorithm.Framework import *
from QuantConnect.Algorithm.Framework.Alphas import *
from Risk.NullRiskManagementModel import NullRiskManagementModel
from datetime import datetime
class AssetClassTrendFollowingAlgorithm(QCAlgorithmFramework):
def Initialize(self):
self.SetStartDate(2007, 5, 1) # Set Start Date
self.SetEndDate(datetime.now()) # Set End Date
self.SetCash(100000) # Set Strategy Cash
self.UniverseSettings.Resolution = Resolution.Daily
symbols = [ Symbol.Create(ticker, SecurityType.Equity, Market.USA) for ticker in ["SPY", "EFA", "BND", "VNQ", "GSG"] ]
self.SetUniverseSelection( ManualUniverseSelectionModel(symbols) )
self.SetAlpha(AssetClassTrendFollowingAlphaModel())
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
self.SetExecution(ImmediateExecutionModel())
self.SetRiskManagement(NullRiskManagementModel())
class AssetClassTrendFollowingAlphaModel(AlphaModel):
'''Alpha model that uses an SMA and security price to create insights'''
def __init__(self,
period = 10*21,
resolution = Resolution.Daily):
'''
Initializes a new instance of the AssetClassTrendFollowingAlphaModel class
Args:
period: The SMA period
'''
self.period = period
self.resolution = resolution
self.predictionInterval = Time.Multiply(Extensions.ToTimeSpan(resolution), period)
self.symbolDataBySymbol = {}
resolutionString = Extensions.GetEnumString(resolution, Resolution)
self.Name = '{}({},{})'.format(self.__class__.__name__, period, resolutionString)
def Update(self, algorithm, data):
'''
Updates this alpha model with the latest data from the algorithm.
This is called each time the algorithm receives data for subscribed securities
Args:
algorithm: The algorithm instance
data: The new data available
Returns:
The new insights generated
'''
insights = []
for symbol, symbolData in self.symbolDataBySymbol.items():
if symbolData.sma.IsReady:
# Emit "up" insight if price exceeds the simple moving average
if algorithm.Securities[symbol].Price > symbolData.smaValue:
insights.append(Insight.Price(symbol, self.predictionInterval, InsightDirection.Up))
return insights
def OnSecuritiesChanged(self, algorithm, changes):
'''
Event fired each time the we add securities from the data feed
Args:
algorithm: The algorithm instance that experienced the change in securities
changes: The security additions and removals from the algorithm
'''
# initialize data for added securities
addedSymbols = [ x.Symbol for x in changes.AddedSecurities ]
history = algorithm.History(addedSymbols, self.period, self.resolution)
for added in changes.AddedSecurities:
algorithm.Log(added)
symbolData = self.symbolDataBySymbol.get(added.Symbol)
if symbolData is None:
# Create SymbolData objects
symbolData = SymbolData(symbol = str(added.Symbol),period = self.period,resolution = self.resolution,algorithm = algorithm)
# Warmup indicators
ticker = SymbolCache.GetTicker(added.Symbol)
symbolData.WarmUpIndicators(history.loc[ticker])
# Add object to dictionary
self.symbolDataBySymbol[added.Symbol] = symbolData
class SymbolData:
'''
Contains data specific to a symbol required by this model
'''
def __init__(self,symbol, period,resolution,algorithm):
self.symbol = symbol
self.algorithm = algorithm
self.sma = self.algorithm.SMA(symbol, period, resolution)
def WarmUpIndicators(self, history):
for tuple in history.itertuples():
self.sma.Update(tuple.Index, tuple.close)
@property
def smaValue(self):
return float(self.sma.Current.Value)