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.
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);
}
}
}
}
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 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.
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.
var orderedMomScores = SectorSymbolData.OrderByDescending(x => x.MomScore).ToList();
var orderedMomScores = SectorSymbolData.OrderByDescending(x => x.MomScore.Current.Value).ToList();
strongSectors = orderedMomScores.Where(val => val.MomScore >= GEMSymbolData[1].MomScore).ToList();
Dictionary GEMSymbolData = new Dictionary();
// in initialize
GEMSymbolData.Add(symbol, new SymbolData(...));
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.
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!