| Overall Statistics |
|
Total Trades 124 Average Win 4.49% Average Loss -0.28% Compounding Annual Return 30.922% Drawdown 58.800% Expectancy 15.297 Net Profit 2463.618% Sharpe Ratio 1.043 Loss Rate 5% Win Rate 95% Profit-Loss Ratio 16.14 Alpha 0.677 Beta -18.38 Annual Standard Deviation 0.299 Annual Variance 0.089 Information Ratio 0.977 Tracking Error 0.299 Treynor Ratio -0.017 Total Fees $1020.19 |
namespace QuantConnect
{
public partial class BasicTemplateAlgorithm : QCAlgorithm
{
//State the two pairs of stocks that you will be using for this strategy
string pair1="MA";
string pair2= "V";
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(2006, 1, 1);
SetEndDate(DateTime.Now.Date.AddDays(-1));
SetCash(cash);
AddSecurity(SecurityType.Equity, pair1, Resolution.Hour);
AddSecurity(SecurityType.Equity, pair2, Resolution.Hour);
//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
decimal allotCash = cash/2m;
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);
}
}
decimal leverage = Portfolio.TotalHoldingsValue / Portfolio.TotalPortfolioValue;
decimal longValue = Securities.Values.Where(x => x.Holdings.Quantity > 0).Sum(y => y.Holdings.AbsoluteHoldingsValue);
decimal shortValue = Securities.Values.Where(x => x.Holdings.Quantity < 0).Sum(y => y.Holdings.AbsoluteHoldingsValue);
foreach (var sec in Securities.Values)
{
decimal relativeValue = sec.Holdings.HoldingsValue / Portfolio.TotalPortfolioValue;
Plot("Relative Performance", sec.Symbol.ToString(), relativeValue);
}
decimal balance = (longValue - shortValue) / (shortValue + longValue + 0.00001m);
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);
Plot("Relative Performance", "Effective Leverage", leverage);
Plot("Relative Performance", "LongShort Balance", balance);
}
}
}