| Overall Statistics |
|
Total Trades 575 Average Win 2.00% Average Loss -0.99% Compounding Annual Return 19.623% Drawdown 24.100% Expectancy 0.895 Net Profit 928.060% Sharpe Ratio 0.958 Loss Rate 37% Win Rate 63% Profit-Loss Ratio 2.02 Alpha 0.141 Beta 0.311 Annual Standard Deviation 0.169 Annual Variance 0.028 Information Ratio 0.49 Tracking Error 0.197 Treynor Ratio 0.519 Total Fees $1443.58 |
using QuantConnect.Indicators;
using System;
using System.Collections.Concurrent;
namespace QuantConnect
{
// Non-barebones implementation of https://seekingalpha.com/article/4120090-horrifically-good-investment-strategy
/*
Little Jack Horner sat in the corner, eating his christmas pie.
He put in his thumb and pulled out a plumb, then said:
"What a good boy am I".
*/
public class BasicTemplateAlgorithm : QCAlgorithm
{
List<string> GrowthUniverse = new List<string>() {
"ATVI","ADBE","AKAM","ALXN","GOOG","GOOGL","AMZN",
"AAL","AMGN","ADI","AAPL","AMAT","ADSK","ADP","BIDU",
"BBBY","BIIB","BMRN","AVGO","CA","CELG","CERN","CHTR",
"CHKP","CSCO","CTXS","CTSH","CMCSA","COST","CSX","CTRP",
"DISCA","DISCK","DISH","DLTR","EBAY","EA","ENDP","EXPE",
"ESRX","FB","FAST","FISV","GILD","HSIC","ILMN","INCY",
"INTC","INTU","ISRG","JD","LRCX","LBTYA","LBTY","LVNTA",
"QVCA","LMCK","BATRA","BATRK","LLTC","MAR","MAT",
"MXIM","MU","MSFT","MDLZ","MNST","MYL","NTAP","NTES","NFLX",
"NCLH","NVDA","NXPI","ORLY","PCAR","PAYX","PYPL","QCOM","REGN",
"ROST","SBAC","STX","SIRI","SWKS","SBUX","SRCL","SYMC","TMUS",
"TSLA","TXN","KHC","PCLN","TSCO","TRIP","FOX","FOXA","ULTA",
"VRSK","VRTX","VIAB","VOD","WBA","WDC","WFM","XLNX","YHOO",
"LMT", "HII", "TLT",
"PKG","A","BSD","BLK","CNX","EVN","ETM","GBL","GS","HT","HGT","JNPR","KFY","LII","NAC","NAN","NAD","NSL","RTEC","SKX","UPS","WCC","DSU","MUC","MUH","MUJ","MUS","CLS","CVG","DHF","EVF","FII","GIL","VVR","LHO","HZO","OME","PAA","RAS","RSG","SCS","WDR","TLI","HIX","MHD","MFL","MHN","BXP","CSU","CBI","CEA","ZNH","CIEN","FIX","CBD","DRQ","EPR","FBR","FDP","BGC","GPI","I,A","ING","KRC","MMS","MTD","NTL","RL","SLG","SAH","SRT","SRI","TSM","URI","MTN","BVN","CCJ","DVD","FDS","FFG","GEL","GES","NUS","REV","SPH","TGI","WG","CLB","DO","DST","EL","MSM","RWT","TRK","WAT","AIV","BZH","COF","CYD","ESS","FGP","FR","GBX","HIW","HNP","BTO","KEP","MAC","MLM","MAA","IIF","NOK","RCS","PLT","PKX","RS","KST","VCO","AWF","BKN","MUA","MVT","BYD","CPT","CBL","KOF","RFI","DDR","DECK","DDF","DUC","ETH","IT","TV","HHS","HR","JBL","MHO","MSD","NTZ","NFX","NTC","NMY","NOM","NNC","NPV","PCM","PMO","REG","RCL","BFS","SQM","SGY","SUI","SKT","TEI","MNP","YPF","GCH","JEQ","BLX","MYC","MCA","MYF","MFT","MIY","MYJ","MYN","MPA","MQT","MQY","ELY","CRT","PFO","KSS","MTX","NAZ","NXC","NXN","NIM","NXP","NXQ","NXR","OHI","ASGN",",OP","SMG","TCO","HQL","USPH","SBI","MMU","MYD","DTF","FCFS","PFD","HAE","HMN","MTG","MSF","NUM","NUO","NQP","NTX","RGS","WNC","SGF","COG","JOF","GF","IRL","MEN","CXE","CXH","DSM","IEX","VLT","MCR","POT","PMM","KSM","TKF","MPV","MIN","HYB","NMI","NNY","PIM","PPT","KTF","BID","TEF","GIM","TTF","USM","ZTR","MHF","CBM","CCL","FUN","CMU","LEO","DNP","MBI","MGF","MMT","NUV","HQH","EMF","TIF","BPL","GAB","GER","KBH","USA","MKL","MFM","ORCL","RVT","TWN","ZF","WTS","FEI"
};
List<string> SafeUniverse = new List<string>() {"TLT"};
public Dictionary<string, Indicators.RateOfChangePercent> _symbolsData = new Dictionary<string, Indicators.RateOfChangePercent>();
int MaxGrowthCount = 10;
bool ShouldRebalance = true;
int Lookback = 22*3;
//Initialize the data and resolution you require for your strategy:
public override void Initialize()
{
//Start and End Date range for the backtest:
SetStartDate(2005, 2, 10);
SetEndDate(DateTime.Now.Date.AddDays(-1));
SetWarmup(Lookback+1);
//Cash allocation
SetCash(25000);
UniverseSettings.Resolution = Resolution.Daily;
foreach(var sec in GrowthUniverse)
{
AddSecurity(SecurityType.Equity, sec, Resolution.Daily);
_symbolsData[sec] = ROCP(sec, Lookback, Resolution.Daily);
}
foreach(var sec in SafeUniverse)
AddSecurity(SecurityType.Equity, sec, Resolution.Daily);
}
string prevMonth = "";
public void OnData(TradeBars data)
{
string month = Time.ToString("MMM");
if(!Portfolio.HoldStock){
Liquidate();
Console.WriteLine("Going growth - Initial");
var leastVolatile = (from _symbol in data.Keys
where _symbolsData[_symbol] > 0
orderby _symbolsData[_symbol] descending
select _symbol).Take(MaxGrowthCount);
foreach(var entry in leastVolatile)
SetHoldings(entry, (decimal)0.78/leastVolatile.Count());
//Order(entry, Math.Floor((Portfolio.Cash*(decimal)0.68)/leastVolatile.Count()));
// Buy 30% Safe
foreach(var entry in SafeUniverse)
SetHoldings(entry, (decimal)0.19/SafeUniverse.Count());
//Order(entry, Math.Floor((Portfolio.Cash*(decimal)0.29)/SafeUniverse.Count()));
}
if(month == "Nov" && prevMonth != "Nov"){
Liquidate();
Console.WriteLine("Going growth");
var leastVolatile = (from _symbol in data.Keys
where _symbolsData[_symbol] > 0
orderby _symbolsData[_symbol] descending
select _symbol).Take(MaxGrowthCount);
foreach(var entry in leastVolatile)
SetHoldings(entry, (decimal)0.78/leastVolatile.Count());
//Order(entry, Math.Floor((Portfolio.Cash*(decimal)0.68)/leastVolatile.Count()));
// Buy 30% Safe
foreach(var entry in SafeUniverse)
SetHoldings(entry, (decimal)0.19/SafeUniverse.Count());
//Order(entry, Math.Floor((Portfolio.Cash*(decimal)0.29)/SafeUniverse.Count()));
}
if(month == "May" && prevMonth != "May"){
Liquidate();
Console.WriteLine("Going safe");
var leastVolatile = (from _symbol in data.Keys
where _symbolsData[_symbol] > 0
orderby _symbolsData[_symbol]
select _symbol).Take(MaxGrowthCount);
foreach(var entry in leastVolatile)
SetHoldings(entry, (decimal)0.29/leastVolatile.Count());
//Order(entry, Math.Floor((Portfolio.Cash*(decimal)0.68)/leastVolatile.Count()));
// Buy 30% Safe
foreach(var entry in SafeUniverse)
SetHoldings(entry, (decimal)0.68/SafeUniverse.Count());
//Order(entry, Math.Floor((Portfolio.Cash*(decimal)0.29)/SafeUniverse.Count()));
}
prevMonth = month;
}
}
}