Overall Statistics |
Total Trades 1 Average Win 0% Average Loss 0% Compounding Annual Return 0.916% Drawdown 2.300% Expectancy 0 Net Profit 0.916% Sharpe Ratio 0.371 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha -0.01 Beta 0.99 Annual Standard Deviation 0.024 Annual Variance 0.001 Information Ratio -0.416 Tracking Error 0.024 Treynor Ratio 0.009 Total Fees $2.44 |
namespace QuantConnect.Rotation { public class GlobalRotation : QCAlgorithm { /* Should we include Money market fund in rotation for growth? If money market has highest momentum it would rotate into it?*/ // 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 "SRLN", // iShares S&P latin america "VMBS", // 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 public override void Initialize() { List<string> allSymbols = GrowthSymbols.Union(SafetySymbols).ToList(); Dictionary<string, SymbolData> allSymbolData = new Dictionary<string, SymbolData>(); SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage); // Portfolio.MarginCallModel = MarginCallModel.Null; double leverage = 1.0; SetCash(25000); SetStartDate(2018, 1, 1); SetEndDate(2019, 1, 1); foreach (var symbol in allSymbols) { AddSecurity(SecurityType.Equity, symbol, Resolution.Daily); var oneMonthPerformance = MOMP(symbol, 21, Resolution.Daily); var threeMonthPerformance = MOMP(symbol, 42, Resolution.Daily); allSymbolData.Add(symbol, new SymbolData { Symbol = symbol, oneMonthPerformanceMOMP = oneMonthPerformance, threeMonthPerformanceMOMP = threeMonthPerformance }); } Schedule.On(DateRules.Every(DayOfWeek.Monday), TimeRules.At(9, 29), () => { IEnumerable<SymbolData> oneMonthOrderedByMOMP = allSymbolData .OrderByDescending(x => x.Value.oneMonthPerformanceMOMP) .Select(x => x.Value) .AsEnumerable(); // assign it's one month rank to the original object in allSymbolData int oneMonthCounter = 0; foreach(var item in oneMonthOrderedByMOMP) { oneMonthCounter++; allSymbolData[item.Symbol].oneMonthRank = oneMonthCounter; }; // get the order based on three month IEnumerable<SymbolData> threeMonthOrderedByMOMP = allSymbolData .OrderByDescending(x => x.Value.threeMonthPerformanceMOMP) .Select(x => x.Value) .AsEnumerable(); // assign it's three month rank to the original object in allSymbolData int threeMonthCounter = 0; foreach(var item in threeMonthOrderedByMOMP) { threeMonthCounter++; allSymbolData[item.Symbol].threeMonthRank = threeMonthCounter; }; // get the new order based on the allSymbolData object's with their shiny new one/threemonth calculated score Dictionary<string, SymbolData> orderedSymbols = allSymbolData.OrderByDescending(x => x.Value.calculateTotalScore()).ToDictionary(); // bank var bestGrowth = orderedSymbols.First().Value; if (bestGrowth.calculateTotalScore() > 0) { if (Portfolio[bestGrowth.Symbol].Quantity == 0) { Log("PREBUY>>LIQUIDATE>>"); Liquidate(); } Log(">>BUY>>" + bestGrowth.Symbol + "@" + (100 * bestGrowth.calculateOneMonthPerformance()).ToString("00.00")); SetHoldings(bestGrowth.Symbol, leverage); } else { // if no one has a good objective score then let's hold cash this month to be safe Log(">>LIQUIDATE>>CASH"); Liquidate(); } }); } public void OnData(TradeBars data) { } } class SymbolData { public string Symbol = ""; public decimal oneMonthWeight = 51; public decimal threeMonthWeight = 49; public decimal oneMonthPerformanceMOMP = 0.0M; public decimal threeMonthPerformanceMOMP = 0.0M; public int oneMonthRank = 0; public int threeMonthRank = 0; public decimal calculateOneMonthPerformance() { return (oneMonthWeight * oneMonthRank / oneMonthWeight); } public decimal calculateThreeMonthPerformance() { return (threeMonthWeight * threeMonthRank / threeMonthWeight); } public decimal calculateTotalScore() { return calculateOneMonthPerformance() + calculateThreeMonthPerformance(); } } }