| Overall Statistics |
|
Total Trades 417 Average Win 0.38% Average Loss -0.07% Compounding Annual Return 15.707% Drawdown 3.500% Expectancy 0.915 Net Profit 15.753% Sharpe Ratio 1.805 Loss Rate 71% Win Rate 29% Profit-Loss Ratio 5.56 Alpha 0.253 Beta -8.122 Annual Standard Deviation 0.067 Annual Variance 0.004 Information Ratio 1.562 Tracking Error 0.067 Treynor Ratio -0.015 Total Fees $761.96 |
class LexxHelp(QCAlgorithm):
def Initialize(self):
'''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''
self.SetStartDate(2013, 12, 31) #Set Start Date
self.SetEndDate(2015, 1, 1) #Set End Date
self.SetCash(100000) #Set Strategy Cash
self.current_month = 12
# what resolution should the data *added* to the universe be?
self.UniverseSettings.Resolution = Resolution.Daily
# An indicator(or any rolling window) needs data(updates) to have a value, doesnt help due to monthly selection?
#self.UniverseSettings.MinimumTimeInUniverse = 10
#self.SetWarmUp(10+1)
# this add universe method accepts two parameters:
self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction)
# Set dictionary of indicators
self.indicators = {}
# Set a list of the selected universe
self.universe = []
self.__numberOfSymbols = 100
self.__numberOfSymbolsFine = 10
self.spy = self.AddEquity("SPY", Resolution.Daily).Symbol
def OnData(self, data):
# This updates the indicators at each data step(based on resolution)
for symbol in self.universe:
# is symbol iin Slice object? (do we even have data on this step for this asset)
if not data.ContainsKey(symbol):
continue
# 686 | 13:35:43: Runtime Error: Python.Runtime.PythonException: AttributeError : 'NoneType' object has no attribute 'Price'
if data[symbol] is None:
continue
# Does this slice have the price data we need at this moment?
if data[symbol].Price is None:
continue
# Either create a new indicator, or update one we already have
if symbol not in self.indicators:
self.indicators[symbol] = SymbolData(symbol, self)
self.indicators[symbol].update_value(self.Time, data[symbol].Price)
# We are warming up the indicators, cannot trade or other stuff
if self.IsWarmingUp: continue
# now you can use logic to trade, random example:
lowerband = self.indicators[symbol].bb_10.LowerBand.Current.Value
upperband = self.indicators[symbol].bb_10.UpperBand.Current.Value
# Log the symbol, price & indicators.
self.Log("{0}\tPrice : {1:0.2f}\tUPPERBAND : {2:0.2f}\tLOWERBAND : {3:0.2f}".format(symbol,
data[symbol].Price,
upperband,
lowerband))
# SLOW, but used to generate some trades.
ma = self.History(symbol, 10).close.mean()
# current price: self.Securities[symbol].Price or data[symbol].Price
if ma < lowerband:
self.SetHoldings(symbol, -0.99/float(len(self.universe)))
elif ma > upperband:
self.SetHoldings(symbol, 0.99/float(len(self.universe)))
# sort the data by daily dollar volume and take the top 'NumberOfSymbols'
def CoarseSelectionFunction(self, coarse):
# sort descending by daily dollar volume
sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
# return the symbol objects of the top entries from our sorted collection
return [ x.Symbol for x in sortedByDollarVolume[:self.__numberOfSymbols] ]
# sort the data by P/E ratio and take the top 'NumberOfSymbolsFine'
def FineSelectionFunction(self, fine):
# sort descending by P/E ratio
sortedByPeRatio = sorted(fine, key=lambda x: x.ValuationRatios.FCFYield, reverse=True)
# resulting symbols
result = [ x.Symbol for x in sortedByPeRatio[:self.__numberOfSymbolsFine] ]
# Only update our universes on a new month? Not sure I like this hack, might work better in coarse to save more resources?
if self.current_month != self.Time.month:
#self.Log(str(self.Time.month)+ " : " +str(len(result)))
self.current_month = self.Time.month
self.universe = result
return result
else:
return self.universe
# this event fires whenever we have changes to our universe
def OnSecuritiesChanged(self, changes):
# liquidate removed securities
for security in changes.RemovedSecurities:
if security.Invested:
self.Liquidate(security.Symbol)
# clean up
del self.indicators[security.Symbol]
class SymbolData(object):
def __init__(self, symbol, context):
self.symbol = symbol
"""
I had to pass ATR from outside object to get it to work, could pass context and use any indica
var atr = ATR(Symbol symbol, int period, MovingAverageType type = null, Resolution resolution = null, Func`2[Data.IBaseData,Data.Market.IBaseDataBar] selector = null)
"""
#self.ema = context.EMA(symbol, self.window)
#self.indicator = context.BB(symbol, self.window)
self.bb_10 = context.BB(symbol,10,2,MovingAverageType.Simple,Resolution.Daily)
#self.indicator2 = context.BB(symbol,20,1,MovingAverageType.Simple,Resolution.Daily)
"""
Runtime Error: Python.Runtime.PythonException: NotSupportedException : AverageTrueRange does not support Update(DateTime, decimal) method overload. Use Update(IBaseDataBar) instead.
"""
#def update_bar(self, bar):
# self.atr.Update(bar)
def update_value(self, time, value):
self.bb_10.Update(time, value)