Overall Statistics |
Total Trades 96 Average Win 4.73% Average Loss -1.91% Compounding Annual Return 30.706% Drawdown 26.600% Expectancy 2.101 Net Profit 1024.610% Sharpe Ratio 1.192 Loss Rate 11% Win Rate 89% Profit-Loss Ratio 2.47 Alpha 0.472 Beta -8.833 Annual Standard Deviation 0.249 Annual Variance 0.062 Information Ratio 1.112 Tracking Error 0.249 Treynor Ratio -0.034 Total Fees $729.22 |
namespace QuantConnect { public partial class BasicTemplateAlgorithm : QCAlgorithm { //State the two pairs of stocks that you will be using for this strategy string pair1="V"; string pair2= "MA"; 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(2009, 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); } } }