| Overall Statistics |
|
Total Trades 1465 Average Win 0.94% Average Loss -0.43% Compounding Annual Return 15.427% Drawdown 28.800% Expectancy 0.647 Net Profit 613.146% Sharpe Ratio 0.795 Loss Rate 48% Win Rate 52% Profit-Loss Ratio 2.16 Alpha 0.276 Beta -8.878 Annual Standard Deviation 0.165 Annual Variance 0.027 Information Ratio 0.696 Tracking Error 0.165 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;
public decimal x;
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,"IEF",Resolution.Daily);
Securities["SPY"].FeeModel = new ConstantFeeTransactionModel(0);
Securities["IEF"].FeeModel = new ConstantFeeTransactionModel(0);
Lev = new RollingWindow<decimal>(5);
SMA1 = SMA("SPY", 10);
SMA2 = SMA("IEF", 10);
//Declare RSI and how to smooth it
rsi1=RSI("SPY", 14, MovingAverageType.Wilders, Resolution.Daily);
smoothedRSI1 = new ExponentialMovingAverage(30).Of(rsi1);
rsi2=RSI("IEF", 14, MovingAverageType.Wilders, Resolution.Daily);
smoothedRSI2 = new ExponentialMovingAverage(30).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("IEF", 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(30).Of(rsi[symbol]);
Securities[symbol].FeeModel = new ConstantFeeTransactionModel(0);
var history = History(symbol, 65);
foreach (var tradeBar in history)
{
rsi[symbol].Update(tradeBar.EndTime, tradeBar.Close);
smoothedRSI[symbol].Update(tradeBar.EndTime, rsi[symbol]);
}
}
change = 0;
}
public void OnData(TradeBars data)
{
//Catches any errors regarding start date
if (data.ContainsKey("IEF"))
{
foreach (var symbol in Symbols)
{
//Report back higher between smoothed rsi of TLT or SPY
var holder = smoothedRSI1;
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 && Portfolio.TotalHoldingsValue < Portfolio.TotalPortfolioValue*2)
{
SetHoldings(symbol, x*1.9m, false, "Long " + symbol);
change = change+1;
}
if (Portfolio[symbol].Invested && smoothedRSI[symbol]<holder)
{
SetHoldings(symbol, 0, false, "Close " + symbol + " Long");
change = change-1;
}
}
var close_ratio = data["SPY"].Close / data["IEF"].Close;
var movAvg_ratio = SMA1/SMA2;
var bullRegime = close_ratio <= movAvg_ratio;
var bearRegime = close_ratio > movAvg_ratio;
Lev.Add(9-change);
if (!Lev.IsReady) return;
var DefQuantity = (Lev[0]*1.9m)/(9);
if (Lev[0] != Lev[1] || Lev[0] == 0)
{
if (bullRegime)
{
SetHoldings("IEF", 0, false, "Close IEF");
SetHoldings("SPY", DefQuantity, false, "SPY Open");
}
if (bearRegime)
{
SetHoldings("SPY", 0, false, "Close SPY");
SetHoldings("IEF", DefQuantity, false, "IEF Open");
}
}
}
}
}
}