| Overall Statistics |
|
Total Trades 1752 Average Win 0.62% Average Loss -0.52% Compounding Annual Return 13.531% Drawdown 24.400% Expectancy 0.374 Net Profit 468.426% Sharpe Ratio 0.793 Loss Rate 37% Win Rate 63% Profit-Loss Ratio 1.20 Alpha 0.241 Beta -7.743 Annual Standard Deviation 0.144 Annual Variance 0.021 Information Ratio 0.679 Tracking Error 0.144 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;
RollingWindow<bool>Regime;
public decimal holder;
public decimal x;
public decimal top;
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);
Regime = new RollingWindow<bool>(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(50).Of(rsi1);
rsi2=RSI("TLT", 14, MovingAverageType.Wilders, Resolution.Daily);
smoothedRSI2 = new ExponentialMovingAverage(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("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(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]);
}
Securities[symbol].FeeModel = new ConstantFeeTransactionModel(0);
}
}
public void OnData(TradeBars data)
{
//Catches any errors regarding start date
if (data.ContainsKey("TLT"))
{
foreach (var symbol in Symbols)
{
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)
{
SetHoldings(symbol, x*1.5m, false, "Long " + symbol);
change = change+1;
}
if (Portfolio[symbol].Invested && smoothedRSI[symbol]<holder)
{
SetHoldings(symbol, 0, false, "Close " + symbol + " Long");
change = change-1;
}
}
var bullRegime = smoothedRSI1 >= smoothedRSI2;
var bearRegime = smoothedRSI1<smoothedRSI2;
Lev.Add(change);
if (!Lev.IsReady) return;
Regime.Add(bullRegime);
if(!Regime.IsReady) return;
var q = ((Portfolio.TotalPortfolioValue*1.7m) - Portfolio.TotalAbsoluteHoldingsCost)/Portfolio.TotalPortfolioValue;
if (Lev[0] != Lev[1] || Regime[0]!=Regime[1] || (Portfolio.TotalAbsoluteHoldingsCost/Portfolio.TotalPortfolioValue) < 1)
{
if (bullRegime)
{
SetHoldings("TLT", 0, false, "Close TLT");
SetHoldings("SPY", q, false, "Alter SPY");
}
if (bearRegime)
{
SetHoldings("SPY", 0, false, "Close SPY");
SetHoldings("TLT", q, false, "Alter TLT");
}
}
}
}
}
}