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

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)

#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...

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):

#REPLACES UPDATE...
for bar in history.itertuples():
tb = TradeBar(bar.Index[1], symbol, bar.open, bar.high, bar.low, bar.close, bar.volume)

@property
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
fastPeriod = 10
slowPeriod = 30
count = 10
self.UOs = {}
self.BB15s = {}
self.U3s = {}
self.L3s = {}
self.DOs = {}
#self.SetUniverseSelection(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:
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:

#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}')
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):

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.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.ub3 = self.uppers[3]
self.lb3 = self.lowers[3]

@property

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.RegisterIndicator(symbol, self.BB, self.consolidator)

self.ub = self.BB.UpperBand
self.lb = self.BB.LowerBand

#MA Cons (NEW)
self.MA = SimpleMovingAverage(12)
algorithm.RegisterIndicator(symbol, self.MA, self.ma_cons)
#self.ma = self.MA #.Current.Value

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

'''
#Dont think I need this?
def OnDataConsolidated(self, sender, bar):
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)

def Update(self, price):
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):

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.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

# Define daily and monthly consolidators
self.monthlyConsolidator = algorithm.Consolidate(symbol, Calendar.Monthly, self.OnMonthlyData)

# Register daily consolistor to algorithm
self.adx.Update(tbar)