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