Overall Statistics |
Total Trades 80 Average Win 1.16% Average Loss -0.31% Compounding Annual Return 6.450% Drawdown 4.500% Expectancy 2.109 Net Profit 33.878% Sharpe Ratio 1.972 Loss Rate 35% Win Rate 65% Profit-Loss Ratio 3.78 Alpha 0.074 Beta -0.527 Annual Standard Deviation 0.032 Annual Variance 0.001 Information Ratio 1.346 Tracking Error 0.032 Treynor Ratio -0.12 Total Fees $265.12 |
namespace QuantConnect.Rotation { public class GlobalRotation : QCAlgorithm { // these are the growth symbols we'll rotate through List<string> GrowthSymbols = new List<string> { "BSJJ", // US S&P mid cap 400 "HYD", // iShares S&P europe 350 "VMBS", // iShared MSCI emerging markets "SRLN", // iShares S&P latin america }; // these are the safety symbols we go to when things are looking bad for growth List<string> SafetySymbols = new List<string> { "CASHX", // Vangaurd TSY 25yr+ // "SHY" // Barclays Low Duration TSY }; // we'll hold some computed data in these guys List<SymbolData> SymbolData = new List<SymbolData>(); public override void Initialize() { SetCash(25000); SetStartDate(2014, 1, 1); SetEndDate(2018, 9, 1); foreach (var symbol in GrowthSymbols.Union(SafetySymbols)) { // ideally we would use daily data AddSecurity(SecurityType.Equity, symbol, Resolution.Minute); var oneMonthPerformance = MOM(symbol, 21, Resolution.Daily); var threeMonthPerformance = MOM(symbol, 42, Resolution.Daily); SymbolData.Add(new SymbolData { Symbol = symbol, OneMonthPerformance = oneMonthPerformance, ThreeMonthPerformance = threeMonthPerformance }); } Schedule.On(DateRules.Every(DayOfWeek.Monday), TimeRules.At(9, 31), () => { OnMonday(); }); } private void OnMonday() { Log("Mon at 12pm: Fired at: " + Time); // pick which one is best from growth and safety symbols var orderedObjScores = SymbolData.OrderByDescending(x => x.ObjectiveScore).ToList(); foreach (var orderedObjScore in orderedObjScores) { Log(">>SCORE>>" + orderedObjScore.Symbol + ">>" + orderedObjScore.ObjectiveScore); } var bestGrowth = orderedObjScores.First(); if (bestGrowth.ObjectiveScore > 0) { if (Portfolio[bestGrowth.Symbol].Quantity == 0) { Log("PREBUY>>LIQUIDATE>>"); Liquidate(); } Log(">>BUY>>" + bestGrowth.Symbol + "@" + (100 * bestGrowth.OneMonthPerformance).ToString("00.00")); SetHoldings(bestGrowth.Symbol, 1.0); } else { // if no one has a good objective score then let's hold cash this month to be safe Log(">>LIQUIDATE>>CASH"); Liquidate(); } } } } class SymbolData { public string Symbol; public Momentum OneMonthPerformance { get; set; } public Momentum ThreeMonthPerformance { get; set; } public decimal ObjectiveScore { get { // we weight the one month performance higher // decimal weight1 = 100; // decimal weight2 = 75; // return (weight1 * OneMonthPerformance + weight2 * ThreeMonthPerformance) / (weight1 + weight2); // we weight the one month performance higher decimal weight1 = 49; decimal weight2 = 51; return (weight1 * OneMonthPerformance + weight2 * ThreeMonthPerformance); } } }