Overall Statistics |
Total Trades 2 Average Win 0.39% Average Loss 0% Compounding Annual Return 0.393% Drawdown 0.200% Expectancy 0 Net Profit 0.393% Sharpe Ratio 0.624 Probabilistic Sharpe Ratio 27.875% Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha 0.003 Beta 0.001 Annual Standard Deviation 0.005 Annual Variance 0 Information Ratio 0.188 Tracking Error 0.153 Treynor Ratio 2.801 Total Fees $22.17 |
''' NOTES re CT III from FUTs #FUCK need to add HIGHS and LOWS to ma -- so need 2 MAs #ha12 and la12 #R1 = Average(High?! of data2-O of data2,12); #S1 = Average(O of data2-L of data2,12); #Cent = (OpenD(0)+CloseD(1))/2; #R2 = Cent + PercentRange*R1; 0 + .5 * R1 #S2 = Cent - PercentRange*S1; #if lower > upper3 #Done #and Close < S2 #DONE #and opend(0) > close //(15M Close) #Do in OnData with TradeBar #Buy Simpler way -- FUCK ult osc and this bullshit trade bar fucking joke. Jesus. for c in sortedByVol: symbol = c.Symbol if symbol not in self.UOs: history = self.History(symbol, 51, Resolution.Daily) self.UOs[symbol] = Ultimate(symbol, history) self.UOs[symbol].Update(c.EndTime, c.AdjustedPrice) #sortedByUO = sorted(self.UOs.items(), key = lambda kv: v.uo_value, reverse=True) if self.UOs[symbol].uo_val > 100: self.longs += [symbol] elif self.UOs[symbol].uo_val < -100: self.shorts += [symbol] self.selected = self.longs + self.shorts FUCK UO In OnData #U3 Version... for symbol in self.selected: if data.Bars.ContainsKey(symbol): if symbol not in self.U3s: hist = self.History(symbol, 25, Resolution.Daily) self.U3s[symbol] = U3(hist, symbol) self.U3s[symbol].Update(data[symbol].EndTime,data[symbol]) #data[symbol].EndTime, #End U3 Version... tradeBars = data.Bars ibmTradeBar = tradeBars['IBM'] class U3(): def __init__(self,history, symbol=None): if symbol: self.symbol = symbol self.uo = UltimateOscillator(9,15,25) for time, price in history.items(): #Manual update... self.Update(time, price) #I think issue is -- ^^ is using history #whereas BELOW is using data['symbol'] def Update(self,time, bar): #Accepts data[sym] as bar #Update in OnData w data['SPY'] AS BAR -> data["SPY"].EndTime , data["SPY"].Close, High, Low etc #Dont kno if I need this line ? Think I already have tradebar. #bar.EndTime #IF not work try with bar! BELOW bar = TradeBar(time, self.symbol, bar.open, bar.high, bar.low, bar.close, bar.Volume) self.uo.Update(bar) #Builtin UO Update method... ''' class DailyBars(): def __init__(self, algorithm, history): self.dailyWindow = RollingWindow[TradeBar](10) #GENIUS #REPLACES UPDATE... self.dailyCons = TradeBarConsolidator(timedelta(days=1)) algorithm.SubscriptionManager.AddConsolidator(symbol, self.dailyCons) for bar in history.itertuples(): tb = TradeBar(bar.Index[1], symbol, bar.open, bar.high, bar.low, bar.close, bar.volume) self.dailyWindow.Add(tb) @property def IsReady(self): return self.dailyWindow.IsReady
#from Selection.EmaCrossUniverseSelectionModel import EmaCrossUniverseSelectionModel from System import * from QuantConnect import * from QuantConnect.Data import * from QuantConnect.Algorithm import * from QuantConnect.Securities import * from QuantConnect import Market from datetime import datetime import pandas as pd class CalibratedOptimizedInterceptor(QCAlgorithm): def Initialize(self): self.SetStartDate(2018, 1, 1) # Set Start Date self.SetEndDate(2019, 1, 1) self.SetCash(100000) # Set Strategy Cash # self.AddEquity("SPY", Resolution.Minute) fastPeriod = 10 slowPeriod = 30 count = 10 self.UOs = {} self.BB15s = {} self.U3s = {} self.L3s = {} self.DOs = {} #self.SetUniverseSelection(self.SelectCoarse) self.AddUniverse(self.SelectCoarse) self.UniverseSettings.Resolution = Resolution.Daily def OnEndOfDay(self): '''Where on earth is this called?''' self.Debug(f'{self.Time.date()} -- {len(self.ActiveSecurities)}') #for security in self.ActiveSecurities.Values: # self.Debug(f"{self.Time.date()} -- {security.Symbol.Value}") def SelectCoarse(self, coarse): sortedByVol = sorted([c for c in coarse if c.AdjustedPrice > 10], key = lambda x: x.DollarVolume, reverse=True)[:100] self.selected = [] self.longs = [] self.shorts = [] #Alt method... new = [s.Symbol for s in sortedByVol if s.Symbol not in self.UOs] if new: history = self.History(new, 51, Resolution.Daily) if history.empty: return Universe.Unchanged history = history.close.unstack(0) for sym in new: if sym in history: #Added? self.UOs[sym] = DBB(history[sym].dropna()) openD, lower, upper, ma12 = 0,0,0,0 for c in sortedByVol: symbol = c.Symbol if symbol not in new and symbol in self.UOs: self.UOs[symbol].Update(c.EndTime, c.AdjustedPrice) #New for U2 if symbol not in self.BB15s: history = self.History(symbol, 25, Resolution.Daily) self.BB15s[symbol] = BB(symbol, self, history) lower = self.BB15s[symbol].lb.Current.Value upper = self.BB15s[symbol].ub.Current.Value ma12 = self.BB15s[symbol].MA.Current.Value #self.Debug(f'{symbol} -- U:{upper} L:{lower} MA:{ma12}') ''' This needs to be ha12 and la12 -- 2 MAs... -- can just average the highs / lows in vecs? ''' openD = history.open.iloc[-1] #-1 or 0? #closeYD = history.close.iloc[-2] Maybe should do windows? #self.Debug(f'{self.U2s[symbol].uo.Current.Value}') if self.UOs[symbol].IsReady and self.BB15s[symbol]: upper3 = self.UOs[symbol].ub3 #Uses Current.Value already! lower3 = self.UOs[symbol].lb3 closeY = self.UOs[symbol].closeDs[1] self.Debug(f'{symbol} -- U3:{upper3} L3:{lower3} CloseY:{closeY}') self.Debug(f'{symbol} -- U:{upper} L:{lower} MA:{ma12}') cent = (openD + closeY) / 2 R2 = cent + .5 * ma12 S2 = cent - .5 * ma12 if lower > upper3 and c.AdjustedPrice > (ma12): #Added in .5 here, to make R2 S2 self.longs += [symbol] if upper < lower3 and c.AdjustedPrice < (ma12): self.shorts += [symbol] self.selected = self.longs + self.shorts self.Debug(f'{self.selected}') return self.selected def SelectFine(self, fine): pass def OnSecuritiesChanged(self, changes): self.Log(f"Added Securities: {[security.Symbol.Value for security in changes.AddedSecurities]}") insights = [] for security in changes.RemovedSecurities: self.Liquidate(security.Symbol) #insights += [Insight.Price(security.Symbol, timedelta(weeks=99), InsightDirection.Flat)] #algorithm.SubscriptionManager.RemoveConsolidator(symbol, self.symbols[symbol].monthlyConsolidator) #algorithm.SubscriptionManager.RemoveConsolidator(symbol, self.symbols[symbol].dailyConsolidator) #self.EmitInsights(insights) def OnData(self, data): '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. Arguments: data: Slice object keyed by symbol containing the stock data ''' if len(self.selected) == 0: return qty = .99 / len(self.selected) self.selected = [sym for sym in self.selected if data.ContainsKey(sym)] bar = data.Bars #Get daily open... For Timing the entries of longs / shorts. for symbol in self.selected: if not data.ContainsKey(symbol): continue sbar = bar[symbol] if symbol not in self.DOs: hist = self.History(symbol, 5, Resolution.Daily) self.DOs[symbol] = DailyOpen(hist) self.DOs[symbol].Update(sbar.Open) #Think this is right? todaysOpen = self.DOs[symbol].todaysOpen #and opend(0) > close //(15M Close) -- NEED to save OPEN of day! #Long Entries self.longs = [sym for sym in self.longs if sym in self.selected ] for symbol in self.longs: if self.Portfolio[symbol].IsLong: continue if not data.ContainsKey(symbol): continue sbar = bar[symbol] #self.Debug(f'open > close ? -- {todaysOpen} > {sbar.Close}') if todaysOpen > sbar.Close: self.SetHoldings(symbol, qty) ''' LONG ONLY #Short Entries -- really just daily timing of them. self.shorts = [sym for sym in self.shorts if sym in self.selected] for symbol in self.shorts: if self.Portfolio[symbol].IsShort: continue if not data.ContainsKey(symbol): continue sbar = bar[symbol] #self.Debug(f'open < close ? -- {todaysOpen} < {sbar.Close}') if todaysOpen < sbar.Close: self.SetHoldings(symbol, -qty) #MAY need to increment entries today? ''' class DBB(): #Need rolling window -- to ADD past DAILY bbs to this... def __init__(self,history): #symbol, #self.window = RollingWindow[float](50) self.closeDs = RollingWindow[float](2) #This is DAILY close #self.opens = RollingWindow[float](2) #Cannot add this, bc only closes passed. self.uppers = RollingWindow[float](5) #New Addit! self.lowers = RollingWindow[float](5) self.ub3 = None self.lb3 = None #self.uo = UltimateOscillator(9, 15, 24) #self.symbol, self.bb = BollingerBands(20,2, MovingAverageType.Simple) self.ub = self.bb.UpperBand self.lb = self.bb.LowerBand #Unstacked one... for time, price in history.items(): self.Update(time, price) def Update(self,time, price): #time, self.bb.Update(time,price) self.uppers.Add(self.ub.Current.Value) #Addits... self.lowers.Add(self.ub.Current.Value) self.closeDs.Add(price) if self.IsReady: self.ub3 = self.uppers[3] self.lb3 = self.lowers[3] @property def IsReady(self): #Addits... return self.bb.IsReady and self.uppers.IsReady and self.lowers.IsReady #self.uo.IsReady #and class BB(): '''15M BBs''' def __init__(self,symbol, algorithm, history): self.BB = BollingerBands(symbol,20,2, MovingAverageType.Simple) # ADDED SYMBOL ^^^^ TO BB self.symbol = symbol algorithm.AddEquity(self.symbol) #?? Need to add I guess.. OKAY! self.consolidator = TradeBarConsolidator(timedelta(minutes=15)) algorithm.SubscriptionManager.AddConsolidator(symbol, self.consolidator) #NEW algorithm.RegisterIndicator(symbol, self.BB, self.consolidator) self.ub = self.BB.UpperBand self.lb = self.BB.LowerBand #MA Cons (NEW) self.MA = SimpleMovingAverage(12) self.ma_cons = TradeBarConsolidator(timedelta(days=1)) algorithm.RegisterIndicator(symbol, self.MA, self.ma_cons) #self.ma = self.MA #.Current.Value #ZO ADDITS ************************ for bar in history.itertuples(): #Manual update... tbar = TradeBar(bar.Index[1], symbol, bar.open, bar.high, bar.low, bar.close, bar.volume) self.consolidator.Update(tbar) self.ma_cons.Update(tbar) self.MA.Update(tbar.EndTime,tbar.Close) #JUST tbar input? self.BB.Update(tbar.EndTime,tbar.Close) # ********************************* #Register / Subscribe to event Don't think this is needed? ^^ that is register #self.consolidator.DataConsolidated += self.OnDataConsolidated @property def IsReady(self): return self.MA.IsReady and self.BB.IsReady ''' #Dont think I need this? def OnDataConsolidated(self, sender, bar): #self.window.Add(bar.Close) self.BB.Update(bar.EndTime, bar.Close) #Might JUST need to be index and bar -- if it's JUST closes? self.MA.Update(bar.EndTime, bar.Close) self.ub = self.BB.UpperBand self.lb = self.BB.LowerBand self.ma = self.MA ''' class DailyOpen(): '''CAN just add TRADEBAR to window, then call w keys -- self.pastBars[0].Open, for ex''' def __init__(self, history): self.opens = RollingWindow[float](5) self.todaysOpen = 0 for bar in history.itertuples(): #for time, price in history.items(): symbol, WAS in tradeBar #tbar = TradeBar(bar.Index[1], bar.open, bar.high, bar.low, bar.close, bar.volume) #self.Update(tbar.Open) #Could simply do self.opens.Add(price.Open) self.opens.Add(bar.open) def Update(self, price): self.opens.Add(price) if self.opens.IsReady: self.todaysOpen = self.opens[0] '''Better Version of ^^^^''' class DailyBars(): '''More efficient version of DailyOpens''' def __init__(self, history): self.daily_opens = RollingWindow[float](5) self.daily_closes = RollingWindow[float](5) self.daily_highs = RollingWindow[float](5) self.daily_lows = RollingWindow[float](5) for time, bar in history.items(): self.Update(bar) def Update(self, bar): self.daily_opens.Add(bar.Open) self.daily_closes.Add(bar.Close) self.daily_highs.Add(bar.High) self.daily_lows.Add(bar.Low) class Momentum(): def __init__(self, history): self.window = RollingWindow[float](275) self.mom_yr = 0 self.mom_mo = 0 for row in history.itertuples(): self.Update(row.close) def Update(self, price): self.window.Add(price) if self.window.IsReady: self.mom_yr = (self.window[25] - self.window[275]) / self.window[275] #Was [-252] and [-25] self.mom_mo = (self.window[0] - self.window[25]) / self.window[25] class SymbolData: def __init__(self, algorithm, symbol): self.algorithm = algorithm self.symbol = symbol # Define daily and monthly rolling windows self.monthlyWindow = RollingWindow[TradeBar](13) self.dailyWindow = RollingWindow[TradeBar](280) # Define daily and monthly consolidators self.monthlyConsolidator = algorithm.Consolidate(symbol, Calendar.Monthly, self.OnMonthlyData) self.dailyConsolidator = TradeBarConsolidator(timedelta(days = 1)) # Register daily consolistor to algorithm algorithm.SubscriptionManager.AddConsolidator(symbol, self.dailyConsolidator) # Define and register ADX indicator self.adxThreshold = 25 self.adx = AverageDirectionalIndex(20) algorithm.RegisterIndicator(symbol, self.adx, self.dailyConsolidator) # Use historical data to warmup rolling windows, consolidators, and indicators history = algorithm.History(symbol, 280, Resolution.Daily) for bar in history.itertuples(): tbar = TradeBar(bar.Index[1], symbol, bar.open, bar.high, bar.low, bar.close, bar.volume) self.dailyWindow.Add(tbar) self.monthlyConsolidator.Update(tbar) self.adx.Update(tbar)