Overall Statistics
Total Trades
318
Average Win
2.29%
Average Loss
-0.48%
Compounding Annual Return
8.560%
Drawdown
7.500%
Expectancy
3.253
Net Profit
247.645%
Sharpe Ratio
1.284
Loss Rate
26%
Win Rate
74%
Profit-Loss Ratio
4.75
Alpha
0.015
Beta
3.465
Annual Standard Deviation
0.064
Annual Variance
0.004
Information Ratio
0.98
Tracking Error
0.064
Treynor Ratio
0.024
Total Fees
$27107.58
namespace QuantConnect 
{   
    public class BasicTemplateAlgorithm : QCAlgorithm
    {
    	public string[] Symbols = {"XLY","XLP","XLE","XLF","XLV","XLI","XLB","XLK","XLU","IYZ","SPY","IEF"};
    	public string[] Sectors = {"XLY","XLP","XLE","XLF","XLV","XLI","XLB","XLK","XLU","IYZ"};
    	
    	private Dictionary<string, RelativeStrengthIndex> rsi = new Dictionary<string, RelativeStrengthIndex>();
    	private Dictionary<string, SimpleMovingAverage> smoothedRSI = new Dictionary<string, SimpleMovingAverage>();
    	private Dictionary<string, decimal> SectorRSI = new Dictionary<string, decimal>();
    	
    	public string Baseline;
    	RollingWindow<string> Regime;
    	RollingWindow<decimal> Value;
    	RollingWindow<decimal> Returns;
    	RollingWindow<decimal> TValue;
    	RollingWindow<decimal> TReturns;
    	
    	public decimal KC;
 
        public override void Initialize() 
        {
            SetStartDate(2003, 1, 1);
            SetEndDate(DateTime.Now);
            SetCash(10000000);
            
			foreach (var symbol in Symbols)
			{
				AddSecurity(SecurityType.Equity,symbol,Resolution.Daily);
            	rsi[symbol]=RSI(symbol, 14, MovingAverageType.Wilders);
            	smoothedRSI[symbol]=new SimpleMovingAverage(100).Of(rsi[symbol]);
            	
            	//Securities[symbol].FeeModel = new ConstantFeeTransactionModel(0);
            	//Securities[symbol].SetLeverage(10);
            
            	var history = History(symbol, 115);
            	foreach (var tradeBar in history)
            	{
            		rsi[symbol].Update(tradeBar.EndTime, tradeBar.Close);
            		smoothedRSI[symbol].Update(tradeBar.EndTime, rsi[symbol]);
        	 	}
        	 	Securities[symbol].SetDataNormalizationMode(DataNormalizationMode.Raw);
			}
			Regime = new RollingWindow<string>(2); 
			
			Value = new RollingWindow<decimal>(2);
			Returns = new RollingWindow<decimal>(50);
			
			TValue = new RollingWindow<decimal>(2);
			TReturns = new RollingWindow<decimal>(50);
        }
        
        public void OnData(Dividends data)
        {
        foreach (var symbol in Symbols){if (data.ContainsKey(symbol))
        {
        	var dividend = data[symbol];
        	var qty = Portfolio[symbol].HoldingsValue / (Portfolio.TotalPortfolioValue - (dividend.Distribution * Portfolio[symbol].Quantity));
        	SetHoldings(symbol, qty, false, "Dividend Reinvestment");
        }}
        }
        
        public void OnData(TradeBars data) 
        {
        	foreach (var symbol in Symbols){if (!data.ContainsKey(symbol)) return;}
        	foreach (var Sector in Sectors)
        	{
        		SectorRSI[Sector] = smoothedRSI[Sector];
        	}
        	
        	
        	/////// BASELINE /////////
        	
        	if (smoothedRSI["SPY"] > smoothedRSI["IEF"]){Baseline = "SPY";} else{Baseline = "IEF";}
        	Regime.Add(Baseline); if (!Regime.IsReady) return;
        	
        	
        	//////// ENTRY RULES //////////////
        
        	int Positions = 4; if (KC > 0){Positions=Convert.ToInt32(Math.Ceiling(KC/.11m));}
        	
        	if ((Regime[0] != Regime[1]||!Portfolio.Invested) && Regime[0] == "IEF")
        	{
        		SetHoldings("IEF", 1, false, "Long Bonds");
        		foreach (var Sector in Sectors)
        		{
        			if (Portfolio[Sector].Invested){SetHoldings(Sector, 0, false, "Close " + Sector);} 
        		}
        	}
        	
        	if ((Regime[0] != Regime[1]||!Portfolio.Invested) && Regime[0] == "SPY")
        	{
        		foreach (var item in SectorRSI.OrderByDescending(key => key.Value).Take(Positions))
				{
        			SetHoldings(item.Key, .1m, false, "Open " + item.Key);
				}
				SetHoldings("IEF", (1-(Positions*.1m)), false, "Proportion Bonds");
        	}
        	
        	
        	//////// KELLY CRITERION //////
        	
        	Value.Add(Portfolio.TotalPortfolioValue); if (!Value.IsReady) return;
         	var Return = (Value[0] - Value[1])/(Value[1]);
         	Returns.Add(Return); if (!Returns.IsReady) return;
         	var StrategyReturns = Returns.Average();
         	
         	double sum = Returns.Sum(d => Math.Pow(Convert.ToDouble(d - StrategyReturns), 2));
     		var ret = Math.Sqrt((sum) / (Returns.Count()-1)); 
     		
			TValue.Add(data["IEF"].Close); if (!TValue.IsReady) return;
         	var TReturn = (TValue[0] - TValue[1])/(TValue[1]);
         	TReturns.Add(TReturn); if (!TReturns.IsReady) return;
			
			var TreasuryReturns = TReturns.Average();
         	var StrategyStDev = Convert.ToDecimal(Math.Pow(ret*100,2));
         	if (StrategyStDev == 0) return;
         	
         	KC = ((StrategyReturns - TreasuryReturns)*100)/(StrategyStDev);
        } 	
    }
}