Getting a build error regarding SymbolData. Trying to attach my code, hopefully it works even without the backtest results. I cloned a previous ETF rotation strategy by MichaelH to start with, and when I build it, it gets the same error as well. I am guessing this is caused by an underlying change in the platform; can anyone help me figure out this issue?
Reuben
namespace QuantConnect { /* * QuantConnect University: Futures Example * * QuantConnect allows importing generic data sources! This example demonstrates importing a futures * data from the popular open data source Quandl. * * QuantConnect has a special deal with Quandl giving you access to Stevens Continuous Futurs (SCF) for free. * If you'd like to download SCF for local backtesting, you can download it through Quandl.com. */ public class DualMomentumSectorRotation : QCAlgorithm { // we'll use this to tell us when the month has ended DateTime LastRotationTime = DateTime.MinValue; TimeSpan RotationInterval = TimeSpan.FromDays(30); string SPY = "SPY"; string ACWI = "ACWI"; string Tbill = "BIL"; string Bonds = "AGG"; List GEMSymbols = new List
{
SPY,
ACWI,
Tbill,
Bonds
};
// these are the growth symbols we'll rotate through
List SectorSymbols = new List
{
"XLV", //healthcare
"XLK", //technology
"XLI", //industrial
"XLU", //utilities
"XLF", //financials
"XLY", //consumerdisc
"XLP", //consumerstap
"XLB", //basic materials
"XLE", // energy
"PSR", //real estate
"IYZ" // communications
};
// we'll hold some computed data in these guys
List SymbolData = new List();
// Indicators
//Momentum _momSPY;
//Momentum _momACWI;
//Momentum _momTbill;
//DateTime sampledToday = DateTime.Now;
public override void Initialize()
{
SetStartDate(2004, 1, 1);
SetEndDate(DateTime.Now.Date.AddDays(-1));
SetCash(25000);
foreach (var symbol in GEMSymbols.Union(SectorSymbols))
{
AddSecurity(SecurityType.Equity, symbol, Resolution.Minute);
Securities[symbol].SetDataNormalizationMode(DataNormalizationMode.TotalReturn);
var momentum = MOM(symbol, 252, Resolution.Daily);
SymbolData.Add(new SymbolData
{
Symbol = symbol,
Momentum = momentum
});
}
}
private bool first = true;
//Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol.
public void OnData(TradeBars data)
{
if (first)
{
first = false;
LastRotationTime = data.Time;
return;
}
var delta = data.Time.Subract(LastRotationTime);
if (delta > RotationInterval)
{
LastRotationTime = data.Time;
var orderedMomScores = SymbolData.OrderByDescending(x => x.MomScore).ToList();
var strongSectors = orderedMomScores.Where(val => val.MomScore >= _momSPY).ToList();
foreach (var score in orderedObjScores)
{
Log(">>SCORE>>" + score.Symbol + ">>" + score.MomScore);
}
foreach (var strongSectorScore in strongSectors)
{
Log(">>SCORE>>" + strongSectorScore.Symbol + ">>" + strongSectorScore.MomScore);
}
}
if (!_momSPY.IsReady) return;
decimal holdingPercent = .5m;
if (_momSPY >= 0 && _momSPY > _momTbill)
{
Liquidate();
foreach (var etf in strongSectors)
{
SetHoldings(etf.Symbol, holdingPercent * (1m / strongSectors.count));
}
} else
{
if(Portfolio[Bonds].Quantity > 0) return;
Liquidate();
SetHoldings(Bonds, holdingPercent);
Log("Set Holdings to " + Portfolio[Bonds].Quantity + "of " + Bonds);
}
}
}
}
Jared Broad
class SymbolData { public string Symbol; public Momentum OneMonthPerformance { get; set; } public Momentum ThreeMonthPerformance { get; set; } public decimal ObjectiveScore { get { // we weight the one month performance higher decimal weight1 = 100; decimal weight2 = 75; return (weight1 * OneMonthPerformance + weight2 * ThreeMonthPerformance) / (weight1 + weight2); } } }
The QC University algorithm "Global ETF Rotation" seems to build fine - which algorithm are you cloning with errors?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.
Michael Handschuh
Reuben
Reuben
Jared Broad
var consolidator = ResolveConsolidator("SPY", TimeSpan.FromDays(30)); // 1 month bars var momentum = new Momentum(12); RegisterIndicator("SPY", momentum, consolidator, Field.Close);
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.
Reuben
Michael Handschuh
var orderedMomScores = SectorSymbolData.OrderByDescending(x => x.MomScore).ToList();
And it's the runtime saying he doesn't know how to compare two instances of Momentum. Try using the following line instead:var orderedMomScores = SectorSymbolData.OrderByDescending(x => x.MomScore.Current.Value).ToList();
I've added to my to-do list to make the indicators IComparable so that they can be ordered as you expected. This line:strongSectors = orderedMomScores.Where(val => val.MomScore >= GEMSymbolData[1].MomScore).ToList();
Will select all instances of SymbolData from the orderedMomScores list that have a momentum higher than GEMSymbolData[1].MomScore. It's not selecting the symbol and THEN the momentum score, it's selecting the instance of SymbolData that contains both of those pieces of information. Also, I would recommend using a dictionary instead of a list so you can index them by string.Dictionary GEMSymbolData = new Dictionary();
// in initialize
GEMSymbolData.Add(symbol, new SymbolData(...));
This way you would be able to access the SPY momentum scoreby GEMSymbolData["SPY"].MomScore. The random constant integers scare me :D. I hope this helps! Let me know if you need anything else!Reuben
Reuben
Michael Handschuh
Reuben
Michael Handschuh
Jared Broad
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.
Reuben
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!