| Overall Statistics |
|
Total Trades 3797 Average Win 0.05% Average Loss -0.07% Compounding Annual Return 10.896% Drawdown 13.100% Expectancy 0.169 Net Profit 20.904% Sharpe Ratio 0.875 Loss Rate 36% Win Rate 64% Profit-Loss Ratio 0.81 Alpha 0.213 Beta -7.448 Annual Standard Deviation 0.103 Annual Variance 0.011 Information Ratio 0.716 Tracking Error 0.103 Treynor Ratio -0.012 Total Fees $4295.04 |
class CoarseFineFundamentalComboAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2017,1,1)
self.SetEndDate(2018,11,1)
self.SetCash(500000)
self.UniverseSettings.Resolution = Resolution.Daily
self.AddEquity("SPY", Resolution.Minute)
self.do_update_fundamentals = 0
self.do_update_signals = 0
self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction)
self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday, DayOfWeek.Monday), self.TimeRules.At(0, 0), Action(self.UpdateFundamentals))
self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday, DayOfWeek.Monday), self.TimeRules.AfterMarketOpen("SPY", 37), Action(self.UpdateSignals))
self.long = None
def CoarseSelectionFunction(self, coarse):
if self.do_update_fundamentals:
sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
return [ x.Symbol for x in sortedByDollarVolume[:100] ]
else:
return []
def FineSelectionFunction(self, fine):
if self.do_update_fundamentals:
sortedByPeRatio = sorted(fine, key=lambda x: x.ValuationRatios.PriceChange1M, reverse=True)
self.do_update_fundamentals = 0
self.long = [ x.Symbol for x in sortedByPeRatio[:40]]
for i in self.long:
self.AddEquity(i.Value, Resolution.Daily)
return self.long
else:
return []
def OnData(self, data):
if self.do_update_signals and self.long:
invested = [x.Key for x in self.Portfolio if x.Value.Invested]
for i in invested:
if i not in self.long:
self.Liquidate(i)
for i in self.long:
self.SetHoldings(i, 0.8/(len(self.long)))
self.do_update_signals = 0
def UpdateFundamentals(self):
self.do_update_fundamentals = 1
def UpdateSignals(self):
self.do_update_signals = 1