Hi, trying to create a strategy where 50% of the portfolio goes to the stocks that fall under some fundamental criteria and the other 50% of the portfolio shorts the SPY index. It is a neutral strategy.
When running the backtest, I can see it simulated some results but near the end of the simulation goes into error and nothing is shown. (find below error and code as I could not attached backtest since it was never completed)
the cloud terminal shows:
Backtest Handled Error: No data loaded for WDFC R735QTJ8XC9X because there were no tradeable dates for this security.
WDFC R735QTJ8XC9X: The security does not have an accurate price as it has not yet received a bar of data. Before placing a trade (or using SetHoldings) warm up your algorithm with SetWarmup, or use slice.Contains(symbol) to confirm the Slice object has price before using the data. Data does not necessarily all arrive at the same time so your algorithm should confirm the data is ready before using it. In live trading this can mean you do not have an active subscription to the asset class you're trying to trade. If using custom data make sure you've set the 'Value' property.
from AlgorithmImports import *
from datetime import timedelta, datetime
from QuantConnect.Data.UniverseSelection import *
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel
from Execution.ImmediateExecutionModel import ImmediateExecutionModel
from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel
class Third_Attempt(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2021, 1, 1) # Set Start Date
self.SetEndDate(2022, 1, 1) # Set Start Date
self.SetCash(100000) # Set Strategy Cash
self.AddUniverseSelection(Highperformance())
self.UniverseSettings.Resolution = Resolution.Daily
self.AddAlpha(BuyPerformance())
self.SetPortfolioConstruction(PortfolioBuilder())
#self.AddRiskManagement(Trailing_SL_TP())
self.SetExecution(ImmediateExecutionModel())
class Highperformance (FundamentalUniverseSelectionModel):
def __init__(self):
super().__init__( True, None)
self.lastMonth = -1
#creating the SPY symbol (for the index)
self.spy = Symbol.Create('SPY', SecurityType.Equity, Market.USA)
def SelectCoarse(self, algorithm, coarse):
#run the algorithm once a month, return Universe.Unchanged in case we are looking at exactly the same month
if algorithm.Time.month == self.lastMonth:
return Universe.Unchanged
self.lastMonth = algorithm.Time.month
sortedByVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
filteredByFundamentals = [x.Symbol for x in sortedByVolume if x.HasFundamentalData]
return filteredByFundamentals + [self.spy]
def SelectFine(self, algorithm, fine):
sorted_high = sorted([x for x in fine if x.MarketCap > 2e9
and 0.5 > x.OperationRatios.AVG5YrsROIC.FiveYears > 0.20
and 50 > x.ValuationRatios.PERatio > 20
and x.AssetClassification.MorningstarSectorCode != MorningstarSectorCode.FinancialServices
and x.AssetClassification.MorningstarSectorCode != MorningstarSectorCode.Healthcare],
key = lambda x: x.ValuationRatios.PERatio, reverse=True)
#fundamental_universe = [x.Symbol for x in sorted_high[:5]] + [self.spy]
return [x.Symbol for x in sorted_high[:5]] + [self.spy]
class BuyPerformance(AlphaModel):
def __init__(self):
self.lastMonth = -1
self.newAdds = []
self.spy = Symbol.Create('SPY', SecurityType.Equity, Market.USA)
def Update(self, algorithm, data):
if algorithm.Time.month == self.lastMonth:
return []
self.lastMonth = algorithm.Time.month
insights = []
#printing the time (for troubleshooting purposes)
algorithm.Debug(str(algorithm.Time))
# Generate Pos (+) insight if the symbol has been added to 'newAdds', has data to trade and has not been invested before
for added in self.newAdds:
if not algorithm.Securities[added].Invested and algorithm.Securities[added].HasData:
algorithm.Debug('Positive Insight : ' + str(added))
insights.append(Insight(added, timedelta(30), InsightType.Price, InsightDirection.Up))
# Generate Flat insight if the symbol is already in the Portfolio, has been invested and it's not in newadds
for x in algorithm.Portfolio:
holding = x.Value
symbol = holding.Symbol
if holding.Invested and (symbol not in self.newAdds):
if symbol not in data.Bars:
continue
insights.append(Insight(symbol, timedelta(30), InsightType.Price, InsightDirection.Flat))
return insights
def OnSecuritiesChanged(self, algorithm, changes):
# When assets are added to the universe, they will trigger OnSecuritiesChanged() event.
#From there, you can initialize any state or history required for the Alpha Model
algorithm.Debug('\n -----ALPHA MODEL ----: ' + str(algorithm.Time))
# Securities added into the universe will be added to self.newAdds
for security in changes.AddedSecurities:
symbol = security.Symbol
if (symbol not in self.newAdds) and (symbol != self.spy):
algorithm.Debug('added symbol : ' + str(symbol))
self.newAdds.append(symbol)
# Securities removed from the universe will be removed from self.newAdds
for security in changes.RemovedSecurities:
symbol = security.Symbol
if symbol in self.newAdds and (symbol != self.spy):
algorithm.Debug('removed symbol symbol : ' + str(symbol))
self.newAdds.remove(symbol)
#Until now we keep excluding the index SPY. We will execute the trade in the portfolio builder
class PortfolioBuilder(PortfolioConstructionModel):
def __init__(self):
self.lastMonth = -1
self.spy = Symbol.Create('SPY', SecurityType.Equity, Market.USA)
def CreateTargets (self, algorithm, insights):
if not algorithm.Time.month == self.lastMonth:
total_equity = algorithm.Portfolio.TotalPortfolioValue
else:
return []
self.lastMonth = algorithm.Time.month
algorithm.Debug('\n -----PORTFOLIO CONSTRUCTION ----: ' + str(algorithm.Time))
# Create a list of PortfolioTarget objects from Insights (just for symbols, excluding SPY)
target_array = []
target = None
new = []
#I am creating a vector of new symbols added to the algorithm
# i will use this vector 'new' to find the lentgh and allocate the right % of the portfolio
for insight in insights:
if not algorithm.Securities[insight.Symbol].Invested:
new.append(insight.Symbol)
for insight in insights:
if insight.Direction == InsightDirection.Flat:
target = PortfolioTarget(insight.Symbol, 0) #Generate the sell order on the flat insight
if insight.Direction == InsightDirection.Up:
#Calculate shares using the half Portfolio value divided in equal amount with the number of symbols recently added.
target = PortfolioTarget.Percent(algorithm, insight.Symbol, 1/(2*len(new)))
target_array.append(target)
#Now i will create the target for the index 'SPY' who's shorting the other half of the portfolio value
for x in algorithm.ActiveSecurities:
holding = x.Value
symbol = holding.Symbol
if not holding.Invested and symbol == self.spy:
target = PortfolioTarget.Percent(algorithm, symbol, -0.5)
target_array.append(target)
return target_array
'''
class Trailing_SL_TP(RiskManagementModel):
def __init__(self):
pass
def ManageRisk(self, algorithm, targets):
pass
'''
Arthur Asenheimer
Duplicate thread, you can find the answer here:
Jose David Delgado Mosquera
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!