| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -16.605 Tracking Error 0.132 Treynor Ratio 0 Total Fees $0.00 |
class UniverseRollingAlgorithm(QCAlgorithm):
def Initialize(self): #Initialize Dates, Cash, Equities, Fees, Allocation, Parameters, Indicators, Charts
# Set Start Date, End Date, and Cash
#-------------------------------------------------------
self.SetStartDate(2020, 4, 22) # Set Start Date
self.SetEndDate(2020, 4, 24) # Set End Date
self.SetCash(100000) # Set Strategy Cash
#-------------------------------------------------------
# Set Custom Universe
#-------------------------------------------------------
self.AddUniverse(self.CoarseSelectionFilter, self.FineSelectionFilter)
self.UniverseSettings.Resolution = Resolution.Daily #Needs to change to Resolution.Minute once code works, leaving Daily for now to minimize data
self.UniverseSettings.SetDataNormalizationMode = DataNormalizationMode.SplitAdjusted
self.UniverseSettings.FeeModel = ConstantFeeModel(0.0)
self.UniverseSettings.Leverage = 1
#-------------------------------------------------------
self.EMA_Period_Fast = 50
self.EMA_Period_Slow = 200
self.UniverseSettings.MinimumTimeInUniverse = self.EMA_Period_Slow
self.SetWarmUp(self.EMA_Period_Slow)
self.__numberOfSymbols = 100
self.__numberOfSymbolsFine = 10
self.indicators = {}
self.fast_ema_window = RollingWindow[IndicatorDataPoint](20)
self.slow_ema_window = RollingWindow[IndicatorDataPoint](20)
def CoarseSelectionFilter(self, coarse):
sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True) # sort descending by daily dollar volume
return [ x.Symbol for x in sortedByDollarVolume[:self.__numberOfSymbols] ] # return the symbol objects of the top entries from our sorted collection
def FineSelectionFilter(self, fine): # sort the data by P/E ratio and take the top 'NumberOfSymbolsFine'
sortedByPeRatio = sorted(fine, key=lambda x: x.OperationRatios.OperationMargin.Value, reverse=False) # sort descending by P/E ratio
self.universe = [ x.Symbol for x in sortedByPeRatio[:self.__numberOfSymbolsFine] ] # take the top entries from our sorted collection
return self.universe
def OnSecuritiesChanged(self, changes):
#self.Log(f"OnSecuritiesChanged({self.Time}):: {changes}"
for security in changes.RemovedSecurities:
if security.Invested:
self.Liquidate(security.Symbol)
del self.indicators[security.Symbol] # clean up
def OnData(self, data): #Entry Point for Data and algorithm - Check Data, Define Buy Quantity, Process Volume, Check Portfolio, Check RSI, Execute Buy/Sell orders, Chart Plots
for symbol in self.universe:
if not data.ContainsKey(symbol): # is symbol in Slice object? (do we even have data on this step for this asset)
continue
if data[symbol] is None: # Runtime Error: Python.Runtime.PythonException: AttributeError : 'NoneType' object has no attribute 'Price'
continue
if data[symbol].Price is None: # Does this slice have the price data we need at this moment?
continue
if symbol not in self.indicators: # new symbol? setup indicator object. Then update
self.indicators[symbol] = SymbolData(symbol, self, self.EMA_Period_Fast, self.EMA_Period_Slow, self.fast_ema_window, self.slow_ema_window)
for symbol in self.universe:
# Check for Indicator Readiness within Rolling Window
#-------------------------------------------------------
if not (self.fast_ema_window.IsReady and self.slow_ema_window.IsReady):
return
#if self.IsWarmingUp: continue
self.indicators[symbol].update_value(self.Time, data[symbol].Price) #update by value
self.Debug("Rolling Fast Index[0] = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].fast_ema_window[0]))
self.Debug("Rolling Fast Index[1] = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].fast_ema_window[1]))
self.Debug("Rolling Slow Index[0] = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[0]))
self.Debug("Rolling Slow Index[1] = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[1]))
'''
self.Debug("RW4F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[4]))
self.Debug("RW5F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[5]))
self.Debug("RW6F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[6]))
self.Debug("RW7F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[7]))
self.Debug("RW8F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[8]))
self.Debug("RW9F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[9]))
self.Debug("RW10F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[10]))
self.Debug("RW11F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[11]))
self.Debug("RW12F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[12]))
self.Debug("RW13F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[13]))
self.Debug("RW14F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[14]))
self.Debug("RW15F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[15]))
self.Debug("RW16F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[16]))
self.Debug("RW17F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[17]))
self.Debug("RW18F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[18]))
self.Debug("RW19F = " + str(symbol) + "-EMA : " + str(self.indicators[symbol].slow_ema_window[19]))
'''
#EXECUTE TRADING LOGIC HERE - PSEUDOCODE FOR NOW
#if self.EMA_FastWin[0] > self.EMA_SlowWin[0] and self.EMA_FastWin[1] < self.EMA_SlowWin[1]:
# buy_order = self.SetHoldings(security.Key, 0.10)
#elif self.EMA_FastWin[0] < self.EMA_SlowWin[0] and self.EMA_FastWin[1] > self.EMA_SlowWin[1]:
# self.Liquidate(security.Key)
class SymbolData(object):
def __init__(self, symbol, context, fast_ema_period, slow_ema_period, fast_ema_window, slow_ema_window):
self.symbol = symbol
self.fast_ema_period = fast_ema_period
self.slow_ema_period = slow_ema_period
self.fast_ema = context.EMA(symbol, self.fast_ema_period)
self.slow_ema = context.EMA(symbol, self.slow_ema_period)
self.fast_ema.Updated += self.EMAUpdated_F
self.slow_ema.Updated += self.EMAUpdated_S
self.fast_ema_window = fast_ema_window #RollingWindow[IndicatorDataPoint](5)
self.slow_ema_window = slow_ema_window #RollingWindow[IndicatorDataPoint](5)
#def update_bar(self, bar):
#self.indicator.Update(bar)
def update_value(self, time, value):
self.fast_ema.Update(time, value)
self.slow_ema.Update(time, value)
def get_fast_EMA(self, context, symbol, period):
return self.fast_ema.Current.Value
def get_slow_EMA(self):
return self.slow_ema.Current.Value
def EMAUpdated_F(self, sender, updated):
self.fast_ema_window.Add(updated) # Adds updated values to rolling window
def EMAUpdated_S(self, sender, updated):
self.slow_ema_window.Add(updated) # Adds updated values to rolling window
#END CODE