| Overall Statistics |
|
Total Trades 1102 Average Win 0.91% Average Loss -0.55% Compounding Annual Return 12.897% Drawdown 20.900% Expectancy 0.533 Net Profit 426.465% Sharpe Ratio 0.781 Loss Rate 42% Win Rate 58% Profit-Loss Ratio 1.66 Alpha 0.23 Beta -7.39 Annual Standard Deviation 0.14 Annual Variance 0.02 Information Ratio 0.663 Tracking Error 0.14 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 (holder == smoothedRSI1)
{
x = x*1.8m;
}
//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*2)
{
SetHoldings(symbol, x, 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.8m) - Portfolio.TotalAbsoluteHoldingsCost)/Portfolio.TotalPortfolioValue;
if (Lev[0] != Lev[1] || Regime[0]!=Regime[1])
{
if (bullRegime)
{
SetHoldings("TLT", 0, false, "Close TLT");
SetHoldings("SPY", q, false, "Fuck SPY");
}
if (bearRegime)
{
SetHoldings("SPY", 0, false, "Fuck SPY");
SetHoldings("TLT", q, false, "TLT Open");
}
}
}
}
}
}