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"); } } } } } }