Hi,

I been struggling with the same error for a bit now, 

Runtime Error: Trying to retrieve an element from a collection using a key that does not exist in that collection throws a KeyError exception. To prevent the exception, ensure that the  key exist in the collection and/or that collection is not empty.  at OnSecuritiesChanged  self.activeStocks.remove(x.Symbol) ===  at Python.Runtime.PyObject.Invoke(PyTuple args in main.py: line 70

I am a bloody beginner and cant figure this one out by myself right now, it might seem obvious to anyone else here on how to fix this. 

If anyone has additional recommendations on this code I am thankfull for any suggestions. 

class WellDressedSkyBlueSardine(QCAlgorithm):

def Initialize(self):
self.SetStartDate(2020, 2, 25)
# self.SetEndDate(2020, 3, 1)
self.SetCash(100000)
self.SetBenchmark("SPY")
self.rebalanceTime = datetime.min
self.activeStocks = set()


self.AddUniverse(self.CoarseFilter, self.FineFilter)
self.UniverseSettings.Resolution = Resolution.Daily

#self.brokerage = BrokerageName.InteractiveBrokersBrokerage
self.SetBrokerageModel(BrokerageName.AlphaStreams)
#self.SetBrokerageModel(self.brokerage, AccountType.Margin)

self.portfolioTargets = []
self.UniverseSettings.DataNormalizationMode=DataNormalizationMode.SplitAdjusted
#self.UniverseSettings.ExtendedMarketHours = False


self.AddRiskManagement(MyRiskModel(.21))
self.SetExecution(ImmediateExecutionModel())
self.SetAlpha(LongOnlyConstantAlphaCreationModel())



def CoarseFilter(self, coarse):
# Rebalancing monthly
if self.Time <= self.rebalanceTime:
return self.Universe.Unchanged
self.rebalanceTime = self.Time + timedelta(2)

myuniverse = [x for x in coarse if x.Price < 50 and x.DollarVolume > 1000000]

return [x.Symbol for x in myuniverse if x.Price < 50
and x.HasFundamentalData][:2000]

def FineFilter(self, fine):
security_filter = [x for x in fine if x.EarningReports.DilutedEPS.Value > .1
and x.ValuationRatios.PERatio < 25
and x.OperationRatios.RevenueGrowth.ThreeMonths > .05
and x.MarketCap > 100000000
and x.OperationRatios.ROA.ThreeMonths > .02
and x.OperationRatios.ROE.ThreeMonths > .03
and x.EarningRatios.DilutedEPSGrowth.ThreeMonths > .03
and x.OperationRatios.NetMargin.ThreeMonths > .08
and x.ValuationRatios.PSRatio < 1.5]


sorting = sorted(security_filter, key = lambda x: x.ValuationRatios.PSRatio, reverse=False)
self.Log(str([x.OperationRatios.RevenueGrowth.ThreeMonths for x in sorting[:50]]))
self.Log(str([x.MarketCap for x in sorting[:50]]))
self.Log(str([x.OperationRatios.ROE.ThreeMonths for x in sorting[:50]]))
self.Log(str([x.OperationRatios.ROA.ThreeMonths for x in sorting[:50]]))
self.Log(str([x.EarningRatios.DilutedEPSGrowth.ThreeMonths for x in sorting[:50]]))
self.Log(str([x.OperationRatios.NetMargin.ThreeMonths for x in sorting[:50]]))
self.Log(str([x.ValuationRatios.PSRatio for x in sorting[:50]]))

return [x.Symbol for x in sorting[:50]]


def OnSecuritiesChanged(self, changes):


# close positions in removed securities
for x in changes.RemovedSecurities:
self.activeStocks.remove(x.Symbol)
self.Liquidate(x.Symbol)


# can't open positions here since data might not be added correctly yet
for x in changes.AddedSecurities:
self.activeStocks.add(x.Symbol)

# adjust targets if universe has changed
self.portfolioTargets = [PortfolioTarget(symbol, 1/len(self.activeStocks))
for symbol in self.activeStocks]



def OnData(self, data):


if self.portfolioTargets == []:
return

for symbol in self.activeStocks:
if symbol not in data:
return

self.SetHoldings(self.portfolioTargets)

# self.portfolioTargets = []





#Riskmodel not working properly
class MyPortfolioModel(EqualWeightingPortfolioConstructionModel):
def __init__(self):
pass

def CreateTargets(self, algorithm, insights):

# Simple insight weighting PCM
targets = []
for insight in insights:
targ = PortfolioTarget(insight.Symbol, insight.Direction*insight.Weight)
targets.append(targ)
return targets

class MyRiskModel(RiskManagementModel):

def __init__(self, maxDrawdown=.21):

self.maxDrawdown = maxDrawdown
self.liquidatedSymbols = set() # Tracks symbols that have been liquidated
self.currentTargets = [] # Tracks state of current targets

def ManageRisk(self, algorithm, targets):

# Reset trackers on new targets
if (set(targets) != self.currentTargets) and len(targets)>0:
algorithm.Log(f'New Targets. Quantity: {targets[0].Quantity}')
self.liquidatedSymbols = set()
self.currentTargets = set(targets)

riskAdjustedTargets = []
for _ in algorithm.Securities:
symbol = _.Key # Symbol object
security = _.Value # Security object
ticker = symbol.Value # String ticker

symbolPnL = security.Holdings.UnrealizedProfitPercent # Current PnL

#Liquidate if exceed drawdown

if (symbolPnL < -self.maxDrawdown) or (ticker in self.liquidatedSymbols):
riskAdjustedTargets.append(PortfolioTarget(symbol, 0))

if algorithm.Securities[symbol].Invested:
self.liquidatedSymbols.add(ticker)
algorithm.Log(f'Trailing stop loss triggered for {ticker}.')

return riskAdjustedTargets

class LongOnlyConstantAlphaCreationModel(AlphaModel):

'''
Description:
This Alpha model creates InsightDirection.Up (to go Long) for a duration of 1 day, every day for all active securities in our Universe
Details:
The important thing to understand here is the concept of Insight:
- A prediction about the future of the security, indicating an expected Up, Down or Flat move
- This prediction has an expiration time/date, meaning we think the insight holds for some amount of time
- In the case of a constant long-only strategy, we are just updating every day the Up prediction for another extra day
- In other words, every day we are making the conscious decision of staying invested in the security one more day
'''

def __init__(self, resolution = Resolution.Daily):

self.insightExpiry = Time.Multiply(Extensions.ToTimeSpan(resolution), 0.25) # insight duration
self.insightDirection = InsightDirection.Up # insight direction
self.securities = [] # list to store securities to consider

def Update(self, algorithm, data):

insights = [] # list to store the new insights to be created

# loop through securities and generate insights
for security in self.securities:
# check if there's new data for the security or we're already invested
# if there's no new data but we're invested, we keep updating the insight since we don't really need to place orders
if data.ContainsKey(security.Symbol) or algorithm.Portfolio[security.Symbol].Invested:
# append the insights list with the prediction for each symbol
insights.append(Insight.Price(security.Symbol, self.insightExpiry, self.insightDirection))
else:
algorithm.Log('excluding this security due to missing data: ' + str(security.Symbol.Value))

return insights

def OnSecuritiesChanged(self, algorithm, changes):

'''
Description:
Event fired each time the we add/remove securities from the data feed
Args:
algorithm: The algorithm instance that experienced the change in securities
changes: The security additions and removals from the algorithm
'''

# add new securities
for added in changes.AddedSecurities:
self.securities.append(added)

# remove securities
for removed in changes.RemovedSecurities:
if removed in self.securities:
self.securities.remove(removed)