Overall Statistics
Total Trades
136
Average Win
2.87%
Average Loss
-2.25%
Compounding Annual Return
9.087%
Drawdown
35.400%
Expectancy
0.733
Net Profit
260.506%
Sharpe Ratio
0.489
Loss Rate
24%
Win Rate
76%
Profit-Loss Ratio
1.28
Alpha
0.091
Beta
-0.108
Annual Standard Deviation
0.179
Annual Variance
0.032
Information Ratio
0.202
Tracking Error
0.269
Treynor Ratio
-0.81
Total Fees
$1270.66
namespace QuantConnect 
{   
    
    public partial class BasicTemplateAlgorithm : QCAlgorithm
    {
      	//State the two pairs of stocks that you will be using for this strategy
    	string pair1="KO";
		string pair2= "PEP";
		int period = 200;
		int firstDay = 0;

		//Create the indicators for Relative Performance and the Standard Deviation
		CompositeIndicator<IndicatorDataPoint> dailyRP;
		CompositeIndicator<IndicatorDataPoint> meanRP;
		StandardDeviation stdDevRP;
		
		//Create checks to enter a strategy once the Relative performance goes
		//below or above a certain standard deviation
		bool checkPos = true;
		bool checkNeg = true;
		
		int cash = 100000;
		
		//Create a variable set the the current time
		//This will be used to make sure you only trade once per day
		DateTime sampledToday = DateTime.Now;
		
        public override void Initialize() 
        {
            SetStartDate(2000, 1, 1);         
            SetEndDate(DateTime.Now.Date.AddDays(-1));
            SetCash(cash); 
            AddSecurity(SecurityType.Equity, pair1, Resolution.Minute);
            AddSecurity(SecurityType.Equity, pair2, Resolution.Minute);
			
			
			//Create daily Relative Performance
			var stock1 = Identity(pair1);
			var stock2 = Identity(pair2);
			dailyRP = stock1.Over(stock2);
			
			//Sum up the prices of stocks for a given period and then create 
			//the Relative Performance Ratio from the result
			var stock1Sum = SUM(pair1, period, Resolution.Daily);
			var stock2Sum = SUM(pair2, period, Resolution.Daily);
			meanRP = stock1Sum.Over(stock2Sum);
			
			//Use the Standard Deviation Indicator to find the Standard Dev of 
			//The Relative Performance Ratio
			StandardDeviation StdDev= new StandardDeviation(period);
			stdDevRP = StdDev.Of(meanRP);
			

			// Chart - Master Container for the Chart:
			var PlotRP = new Chart("Relative Performance");
			
			//On the Relative Performance Chart, we want to show the:
			//Daily Relative Performance, Mean Relative Performance, and 
			//2 standard deviations above and below the mean RP
			PlotRP.AddSeries(new Series("Mean RP", SeriesType.Line, 0));
			PlotRP.AddSeries(new Series("2 Std", SeriesType.Line, 0));
			PlotRP.AddSeries(new Series("-2 Std", SeriesType.Line, 0));
			PlotRP.AddSeries(new Series("daily RP", SeriesType.Line, 0));
			
			//Also, want to plot the points where you make trades
			PlotRP.AddSeries(new Series("Buy "+ pair1 + ", Sell "+ pair2, SeriesType.Scatter, 0));
			//rpPlot.AddSeries(new Series("Sell "+ pair2, SeriesType.Scatter, 0));
			PlotRP.AddSeries(new Series("Buy "+ pair2+ ", Sell "+ pair1, SeriesType.Scatter, 0));			
			//rpPlot.AddSeries(new Series("Sell "+ pair1, SeriesType.Scatter, 0));
			
			//Add the chart to the backtest
			AddChart(PlotRP);
        }

        public void OnData(TradeBars data) 
        {   
			//Don't execute your strategy if one of the stocks does not have data for
			//the time inverval that you chose
			if(data.Count!=2) return;
			
			//establish how much cash you want to spend for each order
			int allotCash = cash/2;
			decimal investPair1=allotCash/(data[pair1].Close);
			decimal investPair2=allotCash/(data[pair2].Close);

			
			//If the date of your check variable is the same as 
			//the date of the stock at that moment, end the program for the day
			//This means that you already executed the strategy that day
			if (sampledToday.Date == data[pair1].Time.Date)return;
			
			
			//If the date is not the same, then set the date to the date 
			//of the stock at that moment, so next time the strategy executes, 
			//it will close since it was already executed that day.
			sampledToday = data[pair1].Time.Date;
			
			
			//Start off with both stocks in your portfolio
			if (firstDay==0)
			{
				Order(pair1, allotCash/data[pair1].Close);
				Order(pair2, allotCash/data[pair2].Close);
				Plot("Relative Performance", "Buy "+ pair2, dailyRP);
				Plot("Relative Performance", "Buy "+ pair1, dailyRP);
				firstDay++;
			}
			
			//Don't start analysis of Relative Performance until the mean RP is
			//fully established
			firstDay++;
			if (firstDay<period)return;
		
			
			//If the daily RP is between the two Standard deviations
			if (checkPos==true && checkNeg==true)
			{
				//If the RP goes above the set point, long the undervalued stock (stock 2),
				//and short the overvalued stock (stock 1)
				//Also, switch the check variable so that when the RP returns back 
				//to normal, you exit the strategy
				if(dailyRP-meanRP>(stdDevRP)*(4/2))
				{
					Order(pair1,-investPair1);
					Order(pair2, investPair2);
					checkPos=false;
				
					Plot("Relative Performance","Buy "+ pair2+ ", Sell "+ pair1, dailyRP);
				}
				
				//If the RP goes above the set point, long the undervalued stock (stock 1),
				//and short the overvalued stock (stock 2)
				else if(dailyRP-meanRP<(-(stdDevRP)*(4/2)))
				{
					Order(pair2,-investPair2);
					Order(pair1,investPair1);
					checkNeg=false;
					
					Plot("Relative Performance","Buy "+ pair1 + ", Sell "+ pair2, dailyRP);
				}
			}
			
			//If the stock goes below the established standard deviation, continue
			//the strategy until you reach equilibrium again.
			else if (checkNeg==false)
			{
				if ((dailyRP-meanRP)>(-stdDevRP)*(1/3))
				{
					Order(pair1,-investPair1);
					Order(pair2,investPair2);
					checkNeg=true;
					
					Plot("Relative Performance","Buy "+ pair2+ ", Sell "+ pair1, dailyRP);
				}
				 
			}
			//If the stock goes above the established standard deviation, continue
			//the strategy until you reach equilibrium again.
			else if (checkPos==false)
			{
				if ((dailyRP-meanRP)<(stdDevRP)*(1/3))
				{
					Order(pair2,-investPair2);
					Order(pair1,investPair1); 
					checkPos=true;
					Plot("Relative Performance","Buy "+ pair1 + ", Sell "+ pair2, dailyRP);
				} 
			}
			
			
			Plot("Relative Performance", "Mean RP", meanRP);
			Plot("Relative Performance", "2 Std", (stdDevRP*2)+meanRP);
			Plot("Relative Performance", "-2 Std", (-stdDevRP*2)+meanRP);
			Plot("Relative Performance", "daily RP", dailyRP);
        }
    }
}