Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
NaN
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
NaN
Tracking Error
NaN
Treynor Ratio
NaN
Total Fees
$0.00
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);
        
       
        
        List<string> GEMSymbols = new List<string>
        {
            "SPY",
            "ACWI",
            "BIL",
            "AGG"
        };
        
        // these are the growth symbols we'll rotate through
        List<string> SectorSymbols = new List<string>
        {
            "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> SectorSymbolData = new List<SymbolData>();
        List<SymbolData> GEMSymbolData = new List<SymbolData>();
        List<SymbolData> strongSectors = new List<SymbolData>();
        
        // 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 SectorSymbols)
            {
                AddSecurity(SecurityType.Equity, symbol, Resolution.Minute);
                Securities[symbol].SetDataNormalizationMode(DataNormalizationMode.TotalReturn);
                var momentum = MOM(symbol, 252, Resolution.Daily);
                
                SectorSymbolData.Add(new SymbolData
                {
                    Symbol = symbol,
                    MomScore = momentum
                });
            }
            
            foreach (var symbol in GEMSymbols)
            {
                AddSecurity(SecurityType.Equity, symbol, Resolution.Minute);
                Securities[symbol].SetDataNormalizationMode(DataNormalizationMode.TotalReturn);
                var momentum = MOM(symbol, 252, Resolution.Daily);
                
                GEMSymbolData.Add(new SymbolData
                {
                    Symbol = symbol,
                    MomScore = 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.Subtract(LastRotationTime);
            
            var _momSPY = GEMSymbolData[1].MomScore;
            var _momTbill = GEMSymbolData[3].MomScore;
            var Bonds = GEMSymbolData[2].Symbol;
            

            if (delta > RotationInterval)
            {
                LastRotationTime = data.Time;
                
                var orderedMomScores = SectorSymbolData.OrderByDescending(x => x.MomScore).ToList();
                strongSectors = orderedMomScores.Where(val => val.MomScore >= GEMSymbolData[1].MomScore).ToList();
                
            
                
                foreach (var x in orderedMomScores)
                {
                    Log(">>SCORE>>" + x.Symbol + ">>" + x.MomScore);
                }
                
                foreach (var y in strongSectors)
                {
                    Log(">>STRONG SCORE>>" + y.Symbol + ">>" + y.MomScore);
                }
                
            }
            
            if (!_momSPY.IsReady) return;
            
            decimal holdingPercent = .5m;
            
            if (_momSPY >= 0 && _momSPY > _momTbill)
            {
                Liquidate();
                foreach (var etf in strongSectors)
                {
                   SetHoldings(etf.Symbol, .1m);
                   Log("Count of stronSectors is "+ 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 MomScore { get; set; }
    }
}