Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 |
namespace QuantConnect { /* Simple 3 ETF Momentum Rotation - script mod by dime 03/06/2016 * Based on Tomer Borenstein's "Global Market Rotation" */ public class SGMR : QCAlgorithm { private string currentWeek; private DateTime currentDay; private MyMomentum momentumETFA; private MyMomentum momentumETFB; private MyMomentum momentumETFC; string currentETF; string ETF1; string ETF2; string ETF3; public override void Initialize(){ // start and End Date range for the backtest: SetStartDate(2016, 2, 1); SetEndDate(DateTime.Now.Date.AddDays(-1)); currentWeek = Time.ToString("WWW"); currentETF = ""; // cash allocation SetCash(100000); //CHANGE SYMBOLS BELOW HERE ------------------------------------- ETF1 = "HYS"; ETF2 = "HYD"; ETF3 = "VMBS"; // CHANGE SYMBOLS ABOVE HERE ------------------------------ AddSecurity(SecurityType.Equity,ETF1, Resolution.Minute); AddSecurity(SecurityType.Equity, ETF2, Resolution.Minute); AddSecurity(SecurityType.Equity, ETF3, Resolution.Minute); // momentum over previous 50 days momentumETFA = new MyMomentum(ETF1, 63); momentumETFB = new MyMomentum(ETF2, 63); momentumETFC = new MyMomentum(ETF3, 63); } public void OnData(TradeBars data){ // day tick - add data to MyMomentum objects if(currentDay.Date != Time.Date){ currentDay = Time; if(data.ContainsKey(ETF1)){ momentumETFA.add(data[ETF1].Close); if(data.ContainsKey(ETF2)){ momentumETFB.add(data[ETF2].Close); if(data.ContainsKey(ETF3)){ momentumETFC.add(data[ETF3].Close); } } // month tick - use momentum to determine which ETF to invest in if(Time.ToString("WWW") != currentWeek){ currentWeek = Time.ToString("WWW"); string ETF = bestETF(); if(currentETF != ETF){ Liquidate(); // cash out // fully invest in best ETF if possible if(data.ContainsKey(ETF)){ decimal cash = Portfolio.Cash; decimal price = data[ETF].Close; int quantity = (int)Math.Floor(cash/price); Order(ETF, quantity); Debug(Time.ToString("WWW") + ": invested in " + ETF + "."); } else { Debug(Time.ToString("WWW") + ": could not invest in " + ETF + "."); } currentETF = ETF; } } } } } // returns the name of the ETF with the best return private string bestETF(){ MyMomentum[] ETFs = new MyMomentum[]{momentumETFA, momentumETFB, momentumETFC }; string bestFund = ""; decimal bestReturn = 0m; for(int i = 0; i < ETFs.Length; i++){ MyMomentum mETF = ETFs[i]; string fund = mETF.getName(); decimal fundReturn = mETF.getReturn(); if(bestFund == "" || bestReturn < fundReturn){ bestFund = fund; bestReturn = fundReturn; } } return bestFund; } } }
using System; using System.Collections; using System.Collections.Generic; using QuantConnect.Securities; using QuantConnect.Models; namespace QuantConnect { // Author: Tomer Borenstein // MyMomentum - calculates a crude measure of an asset's return public class MyMomentum { private List<decimal> prices; private string name; private int window; public MyMomentum(string name, int window){ this.prices = new List<decimal>(); this.name = name; this.window = window; } public void add(decimal price){ prices.Add(price); if(prices.Count > window){ prices.RemoveAt(0); } } public string getName(){ return name; } public decimal getReturn(){ decimal start = prices[0]; decimal end = prices[prices.Count - 1]; return (end-start)/start; } } }