Overall Statistics
Total Trades
856
Average Win
0.15%
Average Loss
-0.22%
Compounding Annual Return
-4.668%
Drawdown
49.400%
Expectancy
0.03
Net Profit
-38.014%
Sharpe Ratio
-0.355
Loss Rate
39%
Win Rate
61%
Profit-Loss Ratio
0.7
Alpha
-0.087
Beta
0.492
Annual Standard Deviation
0.116
Annual Variance
0.013
Information Ratio
-1.139
Tracking Error
0.119
Treynor Ratio
-0.084
Total Fees
$12240.53
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>();
        Dictionary<string, SymbolData> GEMSymbolData = new Dictionary<string, SymbolData>();
        List<string> strongSectors = new List<string>();
        
        // Indicators
        //Momentum _momSPY;
        //Momentum _momACWI;
        //Momentum _momTbill;
        //DateTime sampledToday = DateTime.Now;
        
        

        
        public override void Initialize()
        {
            SetStartDate(2005, 1, 1);         
            SetEndDate(2015, 1, 1); 
            SetCash(25000);
            
            foreach (var symbol in SectorSymbols)
            {
                AddSecurity(SecurityType.Equity, symbol, Resolution.Minute);
                Securities[symbol].SetDataNormalizationMode(DataNormalizationMode.TotalReturn);
                Securities[symbol].SetLeverage(1);
                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);
                Securities[symbol].SetLeverage(1);
                var momentum = MOM(symbol, 252, Resolution.Daily);
                
                GEMSymbolData.Add(symbol, 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) 
        {
            var _momSPY = GEMSymbolData["SPY"].MomScore;
            var _momTbill = GEMSymbolData["BIL"].MomScore;
            var Bonds = GEMSymbolData["ACWI"].Symbol;
            
            decimal holdingPercent = 1m;
            
            if (!_momSPY.IsReady)
            {
                SetHoldings("SPY", holdingPercent);
            }
            
            if (first)
            {
                
                first = false;
                LastRotationTime = data.Time;
                SetHoldings("SPY",holdingPercent);
                return;
            }
            
            var delta = data.Time.Subtract(LastRotationTime);
            
           
            if (delta > RotationInterval)
            {
                LastRotationTime = data.Time;
                
                var orderedMomScores = SectorSymbolData.OrderByDescending(x => x.MomScore.Current.Value).ToList();
                var strongSectorData = orderedMomScores.Where(val => val.MomScore >= _momSPY).ToList();
                
                
                for (int i = 0; i < strongSectorData.Count; i++)
                {
                    strongSectors.Add(strongSectorData[i].Symbol);
                    Log("Strong Symbol #" + i + "is " + strongSectorData[i].Symbol);
                }
                
                
                foreach (var x in orderedMomScores)
                {
                    Log(">>SCORE>>" + x.Symbol + ">>" + x.MomScore);
                }
                
                foreach (var y in strongSectorData)
                {
                    Log(">>STRONG SCORE>>" + y.Symbol + ">>" + y.MomScore);
                }
                
            
                if (_momSPY >= 0 && _momSPY > _momTbill)
                {
                    Liquidate();
                    foreach (var etf in strongSectors)
                    {
                       SetHoldings(etf, holdingPercent * (1m / strongSectors.Count));
                       Log("Count of strongSectors 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; }
    }
}