Overall Statistics |
Total Trades 1504 Average Win 0.06% Average Loss -0.13% Compounding Annual Return -36.066% Drawdown 47.100% Expectancy -0.604 Net Profit -23.679% Sharpe Ratio -0.173 Probabilistic Sharpe Ratio 13.510% Loss Rate 72% Win Rate 28% Profit-Loss Ratio 0.42 Alpha 0 Beta 0 Annual Standard Deviation 0.625 Annual Variance 0.391 Information Ratio -0.173 Tracking Error 0.625 Treynor Ratio 0 Total Fees $1504.00 Estimated Strategy Capacity $64000.00 Lowest Capacity Asset DATS XQYP146WRSDH |
#region imports from AlgorithmImports import * #endregion class TrialHighalgorithm(QCAlgorithm): class SymbolData(object): def __init__(self, symbol, algorithm): self.Symbol = symbol self.algorithm = algorithm # reference to the algorithm object so we can make a history call # this is the buy property that we will use in OnData to filter the symbols that meet our criteria self.buy = False self.sell = False self.symbolSma = SimpleMovingAverage(252) # init windows, most recent value is self.highs[0], second most recent is self.highs[1], etc... self.lows = RollingWindow[float](252) self.highs = RollingWindow[float](252) self.opens = RollingWindow[float](252) self.closes = RollingWindow[float](252) try: history = algorithm.History(symbol, 252, Resolution.Daily) for index, row in history.loc[symbol].iterrows(): self.update(index, row["low"], row["high"], row["open"], row["close"]) except: pass # update windows, sma def update(self, time, low, high, opn, close): self.lows.Add(low) self.highs.Add(high) self.opens.Add(opn) self.closes.Add(close) self.symbolSma.Update(time, close) # add [0] just so that list is not empty during initializing phase self.buy = (max((list(self.highs) + [0])[1:]) < self.highs[0]) & (self.closes[0] > self.opens[0]) #self.sell = (min((list(self.lows) + [0])[1:]) > self.lows[0]) & (self.closes[0] < self.opens[0]) self.sell=(min(list(self.lows))==self.lows[0]) def Initialize(self): self.SetStartDate(2022, 1, 1) #self.SetEndDate(2020, 11, 11) self.SetCash(10000) self.numberOfSymbols = 200 self.res = Resolution.Daily self.averages = {} self.symbols = [] self.sma = {} self.universe = {} self.selectedSymbols = [] self.selectedSymbolss = [] self.SPY = self.AddEquity('SPY', self.res).Symbol self.SetTimeZone(TimeZones.HongKong) self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) self.AddUniverse(self.CoarseSelectionFunction) self.UniverseSettings.Resolution = self.res def CoarseSelectionFunction(self, coarse): filtered = [ x for x in coarse if (x.HasFundamentalData) and (x.Price > 1) and ( x.Volume > 500000) and (x.DollarVolume > 100000) ] filtered.sort(key=lambda x: x.DollarVolume, reverse=True) symbols = [ x.Symbol for x in filtered[:self.numberOfSymbols] ] for symbol in symbols: if symbol not in self.universe: self.universe[symbol] = TrialHighalgorithm.SymbolData(symbol, self) self.sma[symbol] = self.universe[symbol].symbolSma return list(self.universe.keys()) # this is called daily because our resolution is Resolution.Daily def OnData(self, data): # update all the securities in our universe using the latest hihg, open, close data for symbol in self.universe.keys(): # make sure we have data, because sometimes we dont if self.Securities.ContainsKey(symbol) and self.Securities[symbol] != None: time = self.Time low = self.Securities[symbol].Low high = self.Securities[symbol].High opn = self.Securities[symbol].Open close = self.Securities[symbol].Close # update function self.universe[symbol].update(time, low, high, opn, close) # now select all the symbols that meet the buy criteria (this is the 'buy' property of our symboldata object) self.selectedSymbols = [x for x in self.universe.keys() if self.universe[x].buy ] # for x in self.selectedSymbols: # self.SetHoldings(x, 0.01) self.selectedSymbolss = [x for x in self.universe.keys() if self.universe[x].sell ] for x in self.selectedSymbolss: self.SetHoldings(x, -0.01)