Overall Statistics
Total Trades
3883
Average Win
0.40%
Average Loss
-0.30%
Compounding Annual Return
10.554%
Drawdown
18.300%
Expectancy
0.243
Net Profit
295.083%
Sharpe Ratio
0.918
Loss Rate
47%
Win Rate
53%
Profit-Loss Ratio
1.34
Alpha
0.183
Beta
-5.867
Annual Standard Deviation
0.094
Annual Variance
0.009
Information Ratio
0.745
Tracking Error
0.094
Treynor Ratio
-0.015
Total Fees
$0.00
namespace QuantConnect 
{   
    public class BasicTemplateAlgorithm : QCAlgorithm
    {
        //List of the ETFs so we can call them in a foreach instead of one by one
    	public string[] Symbols = {"XLY","XLP","XLE","XLF","XLV","XLI","XLB","XLK","XLU"};
    	
    	//So creating a dictionary allows us to call rsi[symbol] letting us do all the symbols in Symbols at one time
    	private Dictionary<string, RelativeStrengthIndex> rsi = new Dictionary<string, RelativeStrengthIndex>();
    	private Dictionary<string, ExponentialMovingAverage> smoothedRSI = new Dictionary<string, ExponentialMovingAverage>();
    	//This part here is for when we define SPY and TLT which we want to be static and separate from the other ETFS
    	RelativeStrengthIndex rsi1;
    	RelativeStrengthIndex rsi2;
    	private ExponentialMovingAverage smoothedRSI1;
    	private ExponentialMovingAverage smoothedRSI2;
    	public decimal change;
    	SimpleMovingAverage SMA1;
    	SimpleMovingAverage SMA2;
    	RollingWindow<decimal>Lev;
    	public decimal x;
 
        public override void Initialize() 
        {
        	// backtest parameters
            SetStartDate(DateTime.Now-TimeSpan.FromDays(5000));
            SetEndDate(DateTime.Now);
            
            // cash allocation
            SetCash(10000000);
            AddSecurity(SecurityType.Equity,"SPY",Resolution.Daily);
            AddSecurity(SecurityType.Equity,"TLT",Resolution.Daily);
            Securities["SPY"].FeeModel = new ConstantFeeTransactionModel(0);
            Securities["TLT"].FeeModel = new ConstantFeeTransactionModel(0);
            Lev = new RollingWindow<decimal>(5);
            
            SMA1 = SMA("SPY", 10);
            SMA2 = SMA("TLT", 10);
            
            //Declare RSI and how to smooth it
           	rsi1=RSI("SPY", 14, MovingAverageType.Wilders, Resolution.Daily);
           	smoothedRSI1 = new ExponentialMovingAverage(30).Of(rsi1);
           	
           	rsi2=RSI("TLT", 14, MovingAverageType.Wilders, Resolution.Daily);
           	smoothedRSI2 = new ExponentialMovingAverage(30).Of(rsi2);
           	//Create history in the algo so that it pumps 75 bars of data into the algo without having to wait 75 days to trade
           	var history1 = History("SPY", 65);
            foreach (var tradeBar in history1)
            {
            	rsi1.Update(tradeBar.EndTime, tradeBar.Close);
            	smoothedRSI1.Update(tradeBar.EndTime, rsi1);
            }
            
            var history2 = History("TLT", 65);
            foreach (var tradeBar in history2)
            {
            	rsi2.Update(tradeBar.EndTime, tradeBar.Close);
            	smoothedRSI2.Update(tradeBar.EndTime, rsi2);
            }
           	//This says for each etf in Symbols, do the following like add the data, rsi etc
		foreach (var symbol in Symbols)
			{
				AddSecurity(SecurityType.Equity,symbol,Resolution.Daily);
            	rsi[symbol]=RSI(symbol,14, MovingAverageType.Wilders,Resolution.Daily);
            	smoothedRSI[symbol]=new ExponentialMovingAverage(30).Of(rsi[symbol]);
            	Securities[symbol].FeeModel = new ConstantFeeTransactionModel(0);
            
            	var history = History(symbol, 65);
            	foreach (var tradeBar in history)
            	{
            		rsi[symbol].Update(tradeBar.EndTime, tradeBar.Close);
            		smoothedRSI[symbol].Update(tradeBar.EndTime, rsi[symbol]);
        	 	}
			}
			change = 0;
        }
        public void OnData(TradeBars data) 
        {
        	//Catches any errors regarding start date
        	if (data.ContainsKey("TLT"))
        	{
        		foreach (var symbol in Symbols)
        		{
        				//Report back higher between smoothed rsi of TLT or SPY
        			var holder = smoothedRSI1;
        			if (smoothedRSI1<smoothedRSI2)
        			{
        				holder = smoothedRSI2;
        			}
        			else holder = smoothedRSI1;
        			
        			if (symbol == "XLY")
        			{
        				x = .12m;
        			}
        			else if (symbol == "XLP")
        			{
        				x = .09m;
        			}
        			else if (symbol == "XLE")
        			{
        				x = .08m;
        			}
        			else if (symbol == "XLF")
        			{
        				x = .16m;
        			}
        			else if (symbol == "XLV")
        			{
        				x = .14m;
        			}
        			else if (symbol == "XLI")
        			{
        				x = .1m;
        			}
        			else if (symbol == "XLB")
        			{
        				x = .03m;
        			}
        			else if (symbol == "XLK")
        			{
        				x = .2m;
        			}
        			else if (symbol == "XLU")
        			{
        				x = .03m;
        			}
        				
        			//If we are not already in the etf, our smoothed rsi is higher than the holder value, and a quick check to make sure we're not overleveraged
					if (!Portfolio[symbol].Invested && smoothedRSI[symbol]>holder && Portfolio.TotalHoldingsValue < Portfolio.TotalPortfolioValue*2)
            			{
                			SetHoldings(symbol, x, false, "Long " + symbol);
                			change = change+1;
            			}
            		if (Portfolio[symbol].Invested && smoothedRSI[symbol]<holder)
            			{
                			SetHoldings(symbol, 0, false, "Close " + symbol + " Long");
                			change = change-1;
            			}	
        		}
        		var close_ratio = data["SPY"].Close / data["TLT"].Close;
				var movAvg_ratio = SMA1/SMA2;
							
				var bullRegime = close_ratio <= movAvg_ratio;
				var bearRegime = close_ratio > movAvg_ratio;
				
        		Lev.Add(9-change);
        		if (!Lev.IsReady) return;
        		
        		var DefQuantity = ((Portfolio.TotalPortfolioValue) - Portfolio.TotalAbsoluteHoldingsCost)/Portfolio.TotalPortfolioValue;
        		
        		if (Lev[0] != Lev[1] || Lev[0] == 0 || (Portfolio.TotalAbsoluteHoldingsCost/Portfolio.TotalPortfolioValue) < .9m)
        		{
        			if (bullRegime)
        			{
        				SetHoldings("TLT", 0, false, "Close TLT");
						SetHoldings("SPY", DefQuantity, false, "SPY Open");
        			}
        			if (bearRegime)
        			{
        				SetHoldings("SPY", 0, false, "Close SPY");
						SetHoldings("TLT", DefQuantity, false, "TLT Open");
        			}
        		}
        	}
        }
    }
}