import pandas as pd
class SleepyYellowGreenTapir(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 1, 2)
self.SetEndDate(2020, 1, 10)
self.SetCash(100000)
self.AddUniverse(self.CoarseFilter, self.FineFilter)
self.UniverseSettings.Resolution = Resolution.Daily
self.macd_indicator = dict()
self.capacity = 20
# 5. Hedge stratigic assets
# 6. Schedule functions
# self.Schedule.On(
# self.DateRules.EveryDay(),
# self.TimeRules.At(14, 40),
# self.MonitorAndExit
# )
# self.Schedule.On(
# self.DateRules.EveryDay(),
# self.TimeRules.At(14, 50),
# self.MonitorAndEnter
# )
# def MonitorAndExit(self):
# self.Debug("MonitorAndExit fired at: {0}".format(self.Time))
# def MonitorAndEnter(self):
# self.Debug("MonitorAndEnter fired at: {0}".format(self.Time))
# for key, value in self.macd_indicator.items():
# if not value.IsReady:
# self.Debug(f'MACD {key} warm up not ready')
# return
# else:
# self.Debug(f'MACD warm up are ready!!!')
# invested_list = [x.Key for x in self.Portfolio if x.Value.Invested]
# invested = len(invested_list)
# open_order = 0
# for key, value in self.macd_indicator.items():
# if invested + open_order >= self.capacity:
# break
# if self.macd_indicator[key].Histogram.Current.Value > 0:
# self.SetHoldings(key, 1/self.capacity)
# open_order += 1
def CoarseFilter(self, coarse):
return [x.Symbol for x in coarse if x.HasFundamentalData]
def FineFilter(self, fine):
# Tech industry
filteredFine = [x for x in fine if x.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Technology]
sortedByPERatio = sorted(filteredFine, key=lambda f: f.ValuationRatios.PERatio, reverse=True)[:int(0.6*len(filteredFine))]
sortedByEPS = sorted(filteredFine, key=lambda f: f.EarningReports.BasicEPS.ThreeMonths, reverse=True)[:int(0.6*len(filteredFine))]
sortedByROE = sorted(filteredFine, key=lambda f: f.OperationRatios.ROE.ThreeMonths, reverse=True)[:int(0.6*len(filteredFine))]
sortedByNetIncome = sorted(filteredFine, key=lambda f: f.FinancialStatements.IncomeStatement.NetIncome.ThreeMonths, reverse=True)[:int(0.6*len(filteredFine))]
s = set()
s = set(sortedByPERatio) & set(sortedByEPS) & set(sortedByROE) & set(sortedByNetIncome)
# Sort the list by pb ratio
return [x.Symbol for x in sorted(list(s), key=lambda f: f.ValuationRatios.PBRatio, reverse=True)]
def OnSecuritiesChanged(self, changes):
# close positions in removed securities
for x in changes.RemovedSecurities:
symbol = x.Symbol
# Remove rolling windows
if symbol in self.macd_indicator:
del self.macd_indicator[symbol]
self.Debug(f'AddedSecurities: {len(changes.AddedSecurities)}')
# can't open positions here since data might not be added correctly yet
for x in changes.AddedSecurities:
symbol = x.Symbol
if symbol not in self.macd_indicator:
self.macd_indicator[symbol] = self.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
warmUpData = self.History(symbol, 40, Resolution.Daily)
for bar in warmUpData.loc[symbol, :].itertuples():
self.macd_indicator[symbol].Update(bar.Index, bar.close)
# Add rolling windows
# self.Debug(f'{symbol} warm up done')
# 2. Add MACD indicators and Awesome indicators
# 4. Add hedge symbols
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
'''
self.Debug(f'Today is {self.Time} in OnData')
for key, value in self.macd_indicator.items():
if not value.IsReady:
self.Debug(f'MACD {key} warm up not ready')
return
else:
self.Debug(f'MACD warm up are ready!!!')
# TODO: Need to update the security that are not in above security list??
# self.Debug(f'Dir: {dir(data)}')
# self.Debug(f'Type: {type(data)}')
# self.Debug(f'Dir 2: {dir(data.Bars)}')
# self.Debug(f'Type 2: {type(data.Bars)}')
# for key, value in self.macd_indicator.items():
# self.Debug(f'Updating {key} MACD')
# value.Update(self.Time, data.Bars[key])
# pass
# self.Debug(f'Key: {key}\n' +
# f'Fast: {self.macd_indicator[key].Fast.Current.Value}\n' +
# f'Slow: {self.macd_indicator[key].Slow.Current.Value}\n' +
# f'Signal: {self.macd_indicator[key].Signal.Current.Value}\n' +
# f'Hist: {self.macd_indicator[key].Histogram.Current.Value}\n'
# )
# self.Debug(self.macd_indicator[key].ToDetailedString())
invested_list = [x.Key for x in self.Portfolio if x.Value.Invested]
invested = len(invested_list)
open_order = 0
for key, value in self.macd_indicator.items():
if invested + open_order >= self.capacity:
break
if self.macd_indicator[key].Histogram.Current.Value > 0:
self.SetHoldings(key, 1/self.capacity)
open_order += 1
# 2. Add MACD indicators and Awesome indicators
# 3. Make the trade
pass