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