| Overall Statistics |
|
Total Trades 238 Average Win 0.53% Average Loss -0.43% Compounding Annual Return 3.466% Drawdown 9.600% Expectancy 0.036 Net Profit 1.732% Sharpe Ratio 0.279 Probabilistic Sharpe Ratio 28.704% Loss Rate 54% Win Rate 46% Profit-Loss Ratio 1.24 Alpha 0.011 Beta 0.092 Annual Standard Deviation 0.136 Annual Variance 0.019 Information Ratio -1.473 Tracking Error 0.173 Treynor Ratio 0.414 Total Fees $261.98 Estimated Strategy Capacity $680000.00 Lowest Capacity Asset IHF TIDDZIE7WNZ9 |
import heapq
class PensiveBlackSalamander(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2021, 1, 28)
self.SetCash(100000)
self.AddUniverse(self.MyCoarseFilterFunction)
self.selected = []
self.UniverseSettings.Resolution = Resolution.Daily
self.dataBySymbol = {}
self.AddEquity("SPY")
self.Schedule.On(self.DateRules.MonthStart("SPY"), \
self.TimeRules.AfterMarketOpen("SPY"), \
self.liquidate)
def liquidate(self):
self.Liquidate()
def MyCoarseFilterFunction(self, coarse):
sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
filtered = [ x for x in sortedByDollarVolume
if x.Price > 10 and x.DollarVolume > 10000000 ]
# probably want some different logic for filtered or none at all
# filtered = filtered[:20]
filtered = filtered
self.selected = []
self.heap = []
for x in filtered:
if x.Symbol not in self.dataBySymbol:
self.dataBySymbol[x.Symbol] = SymbolData(self,x.Symbol)
self.dataBySymbol[x.Symbol].roc.Update(self.Time,x.Price)
self.dataBySymbol[x.Symbol].rocd.Update(self.Time,x.Price)
if self.dataBySymbol[x.Symbol].IsReady:
#https://docs.python.org/3/library/heapq.html
heapq.heappush(self.heap, (self.dataBySymbol[x.Symbol].rocd.Current.Value, x.Symbol))
# choose the 5 largest in the heap
for h in heapq.nlargest(5,self.heap):
self.selected.append(h[1])
self.Debug(str(self.selected))
return self.selected
def OnData(self, data):
for symbol in self.selected:
if not self.Portfolio[symbol].Invested:
self.SetHoldings(symbol,1/len(self.selected))
def OnSecuritiesChanged(self,changes):
for x in changes.RemovedSecurities:
self.dataBySymbol.pop(x.Symbol,None)
self.Liquidate(x.Symbol)
class SymbolData:
def __init__(self,algo,symbol):
self.roc = RateOfChange(252)
self.rocd = IndicatorExtensions.Of(Delay(21), self.roc)
self.symbol = symbol
history = algo.History(symbol,252,Resolution.Daily)
if not history.empty:
for time, row in history.loc[symbol].iterrows():
self.roc.Update(time,row['close'])
self.rocd.Update(time,row['close'])
@property
def IsReady(self):
return self.roc.IsReady
return self.rocd.IsReady