Overall Statistics |
Total Trades 383 Average Win 1.05% Average Loss -0.13% Compounding Annual Return 6.302% Drawdown 14.400% Expectancy 3.998 Net Profit 151.943% Sharpe Ratio 0.636 Loss Rate 47% Win Rate 53% Profit-Loss Ratio 8.36 Alpha 0.113 Beta -3.637 Annual Standard Deviation 0.084 Annual Variance 0.007 Information Ratio 0.442 Tracking Error 0.084 Treynor Ratio -0.015 Total Fees $0.00 |
namespace QuantConnect { public class BasicTemplateAlgorithm : QCAlgorithm { public string[] Symbols = {"XLY","XLP","XLE","XLF","XLV","XLI","XLB","XLK","XLU","IYZ","SPY","IEF","TLT"}; public string[] Sectors = {"XLY","XLP","XLE","XLF","XLV","XLI","XLB","XLK","XLU","IYZ"}; private Dictionary<string, RelativeStrengthIndex> rsi = new Dictionary<string, RelativeStrengthIndex>(); private Dictionary<string, SimpleMovingAverage> smoothedRSI = new Dictionary<string, SimpleMovingAverage>(); private Dictionary<string, decimal> Weight = new Dictionary<string, decimal>(); public string Baseline; RollingWindow<string> Regime; public decimal MaxWeight; RollingWindow<decimal> Profit; RollingWindow<decimal> ProfitWins; RollingWindow<decimal> ProfitLosses; RollingWindow<decimal> WLCount; public decimal Kelly; public int Counter; public decimal B; public decimal P; RollingWindow<decimal> SpyClose; RollingWindow<decimal> Holdings; public override void Initialize() { SetStartDate(2003, 1, 1); SetEndDate(DateTime.Now); SetCash(10000000); foreach (var symbol in Symbols) { AddSecurity(SecurityType.Equity,symbol,Resolution.Daily); rsi[symbol]=RSI(symbol, 14, MovingAverageType.Wilders); smoothedRSI[symbol]=new SimpleMovingAverage(120).Of(rsi[symbol]); Securities[symbol].FeeModel = new ConstantFeeTransactionModel(0); Securities[symbol].SetLeverage(5); var history = History(symbol, 135); foreach (var tradeBar in history) { rsi[symbol].Update(tradeBar.EndTime, tradeBar.Close); smoothedRSI[symbol].Update(tradeBar.EndTime, rsi[symbol]); } } Weight.Add("XLY", .12m); Weight.Add("XLP", .09m); Weight.Add("XLE", .08m); Weight.Add("XLF", .16m); Weight.Add("XLV", .14m); Weight.Add("XLI", .1m); Weight.Add("XLB", .03m); Weight.Add("XLK", .2m); Weight.Add("XLU", .03m); Weight.Add("IYZ", .02m); Regime = new RollingWindow<string>(2); Profit = new RollingWindow<decimal>(2); ProfitWins = new RollingWindow<decimal>(41); ProfitLosses = new RollingWindow<decimal>(41); WLCount = new RollingWindow<decimal>(41); SpyClose = new RollingWindow<decimal>(31); Holdings = new RollingWindow<decimal>(2); } public void OnData(TradeBars data) { foreach (var symbol in Symbols){if (!data.ContainsKey(symbol)) return;} if (smoothedRSI["SPY"] > smoothedRSI["IEF"]){Baseline = "SPY";} else{Baseline = "IEF";} Regime.Add(Baseline); if (!Regime.IsReady) return; //////// Calculating How Many Sectors Will Be Opened //////// foreach (var Sector in Sectors) { if (!Portfolio[Sector].Invested && smoothedRSI[Sector] > smoothedRSI[Baseline]) { MaxWeight = MaxWeight + Weight[Sector]*2; } if (Portfolio[Sector].Invested && smoothedRSI[Sector] < smoothedRSI[Baseline]) { MaxWeight = MaxWeight - Weight[Sector]*2; } } //////// Opening Positions in the Sectors so that Allocation will be (100% of Total Value) * Kelly Criterion //////// foreach (var Sector in Sectors) { if (!Portfolio[Sector].Invested && smoothedRSI[Sector] > smoothedRSI[Baseline]) { var x = Weight[Sector]/MaxWeight; if (Kelly != 0){x = (Kelly);} SetHoldings(Sector, .01m, false, "Odds are " + Math.Round(B,2) + " and Win % is " + Math.Round(P*100,2)); } if (Portfolio[Sector].Invested && smoothedRSI[Sector] < smoothedRSI[Baseline]) { SetHoldings(Sector, 0, false, "Close " + Sector); Profit.Add(Portfolio[Sector].LastTradeProfit); if(!Profit.IsReady) return; var Return = Profit[0]; if (Return > 0) { ProfitWins.Add(Return); ++Counter; } if (Return <= 0) { ProfitLosses.Add(Math.Abs(Return)); } WLCount.Add(Counter); } } ///////// Opening Positions in the Benchmark so that Allocation will be (100% of Total Value) * Kelly Criterion ////// if (Regime[0] != Regime[1]) { SetHoldings(Regime[1], 0, false, "Close " + Regime[1]); var x = 1.0m; if (Kelly != 0){x = (Kelly);} SetHoldings(Regime[0], x, false, "Open " + Regime[0]); } ////////// KELLY CRITERION CALCULATIONS ////////////// if (!(ProfitWins.IsReady && ProfitLosses.IsReady && WLCount.IsReady)) return; P = (WLCount[0] - WLCount[40])/40; B = ProfitWins.Average(); if (ProfitLosses.Average()!=0) { B = (ProfitWins.Average()) / (ProfitLosses.Average()); } if (B != 0) { Kelly = (P - ((1-P)/(B))); } Plot("Chart", "Kelly Criterion", Kelly); } } }