Overall Statistics
Total Trades
814
Average Win
0.71%
Average Loss
-0.44%
Compounding Annual Return
5.795%
Drawdown
25.000%
Expectancy
0.501
Net Profit
135.349%
Sharpe Ratio
0.659
Loss Rate
42%
Win Rate
58%
Profit-Loss Ratio
1.61
Alpha
0.021
Beta
0.325
Annual Standard Deviation
0.074
Annual Variance
0.005
Information Ratio
-0.296
Tracking Error
0.123
Treynor Ratio
0.15
Total Fees
$814.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, SimpleMovingAverage> smoothedRSI = new Dictionary<string, SimpleMovingAverage>();
    	//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 SimpleMovingAverage smoothedRSI1;
    	private SimpleMovingAverage smoothedRSI2;
    	RollingWindow<decimal> HoldCost;
    	public bool change;
    	SimpleMovingAverage SMA1;
    	SimpleMovingAverage SMA2;
    	public decimal cash;
 
        public override void Initialize() 
        {
        	// backtest parameters
            SetStartDate(2002, 8, 1);
            SetEndDate(DateTime.Now);
            
            // cash allocation
            SetCash(10000);
            AddSecurity(SecurityType.Equity,"SPY",Resolution.Daily);
            AddSecurity(SecurityType.Equity,"IEF",Resolution.Daily);
            
            SMA1 = SMA("SPY", 10);
            SMA2 = SMA("IEF", 10);
            
            //Declare RSI and how to smooth it
           	rsi1=RSI("SPY", 14, MovingAverageType.Wilders, Resolution.Daily);
           	smoothedRSI1 = new SimpleMovingAverage(50).Of(rsi1);
           	
           	rsi2=RSI("IEF", 14, MovingAverageType.Wilders, Resolution.Daily);
           	smoothedRSI2 = new SimpleMovingAverage(50).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("IEF", 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 SimpleMovingAverage(50).Of(rsi[symbol]);
            
            	var history = History(symbol, 65);
            	foreach (var tradeBar in history)
            	{
            		rsi[symbol].Update(tradeBar.EndTime, tradeBar.Close);
            		smoothedRSI[symbol].Update(tradeBar.EndTime, rsi[symbol]);
        	 	}
			}
			HoldCost = new RollingWindow<decimal>(5);
        }
        public void OnData(TradeBars data) 
        {
        	//Catches any errors regarding start date
        	if (data.ContainsKey("IEF"))
        	{
        		change = false;
        		//This keeps track of our rebalance
        		foreach (var symbol in Symbols)
        		{
        			if (smoothedRSI[symbol].IsReady)
        			{
        				//Report back higher between smoothed rsi of TLT or SPY
        				var holder = smoothedRSI1;
        				if (smoothedRSI1<smoothedRSI2)
        				{
        					holder = smoothedRSI2;
        				}
        				else holder = smoothedRSI1;
        				
        				//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)
            				{
                				SetHoldings(symbol, .11111m, false, "Long " + symbol);
                				change = false;
                				cash = Portfolio.Cash;
            				}
            			if (Portfolio[symbol].Invested && smoothedRSI[symbol]<holder)
            				{
                				SetHoldings(symbol, 0, false, "Close " + symbol + " Long");
                				change = false;
                				
                				var DefQuantity = ((cash)/(Portfolio.TotalPortfolioValue));
        					
        						var close_ratio = data["SPY"].Close / data["IEF"].Close;
								var movAvg_ratio = SMA1/SMA2;
							
								var bullRegime = close_ratio <= movAvg_ratio;
								var bearRegime = close_ratio > movAvg_ratio;
							
        						if (bullRegime)
        						{
        							SetHoldings("IEF", 0, false, "Close IEF");
									SetHoldings("SPY", DefQuantity, false, "SPY Open");
        						}
        						if (bearRegime)
        						{
        							SetHoldings("SPY", 0, false, "Close SPY");
									SetHoldings("IEF", DefQuantity, false, "IEF Open");
        						}
            				}
        			}
        		}
        		Log("Leverage Ratio = " + (Portfolio.TotalAbsoluteHoldingsCost/Portfolio.TotalPortfolioValue));
        	}
        }
    }
}