Overall Statistics |
Total Trades 89 Average Win 0.58% Average Loss -0.78% Compounding Annual Return 38.972% Drawdown 9.400% Expectancy 0.447 Net Profit 24.715% Sharpe Ratio 2.924 Probabilistic Sharpe Ratio 91.630% Loss Rate 17% Win Rate 83% Profit-Loss Ratio 0.74 Alpha 0.327 Beta -0.054 Annual Standard Deviation 0.11 Annual Variance 0.012 Information Ratio 1.227 Tracking Error 0.176 Treynor Ratio -5.934 Total Fees $124.88 |
namespace QuantConnect.Algorithm.CSharp { public class PriceIndexAlphaModel : IAlphaModel { List<Symbol> symbols = new List<Symbol>(); public void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes) { foreach (var added in changes.AddedSecurities) { symbols.Add(added.Symbol); } foreach (var removed in changes.RemovedSecurities) { symbols.Remove(removed.Symbol); } } public IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice data) { List<Insight> insights = new List<Insight>(); foreach (var symbol in symbols) { if (!algorithm.Portfolio[symbol].Invested) { insights.Add(new Insight(symbol, new TimeSpan(180, 0, 0, 0, 0), InsightType.Price, InsightDirection.Up)); } } return insights; } } public class ActiveUniverseTest : QCAlgorithm { private bool _rebalance = true; private DateTime lastRebalance; public override void Initialize() { SetStartDate(2016, 1, 1); SetEndDate(2016, 9, 1); SetCash(100000); UniverseSettings.Resolution = Resolution.Daily; AddUniverse(SelectCoarse, SelectFine); AddAlpha(new PriceIndexAlphaModel()); SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel(time => null)); SetExecution(new ImmediateExecutionModel()); } public IEnumerable<Symbol> SelectCoarse(IEnumerable<CoarseFundamental> coarse) { if (!_rebalance) return Universe.Unchanged; var stocks = (from c in coarse where c.DollarVolume > 300000 && c.DollarVolume < 2000000 && c.Price > 5 where c.HasFundamentalData orderby c.DollarVolume descending select c.Symbol).Take(500); return stocks; } public IEnumerable<Symbol> SelectFine(IEnumerable<FineFundamental> fine) { if (!_rebalance) return Universe.Unchanged; var sortedByPriceIndex = from stock in fine where stock.MarketCap < 1000000000 let history = History<TradeBar>(stock.Symbol, new TimeSpan(180, 0, 0), Resolution.Daily) where history.Count() > 0 let priceIndex = history.Last().Close - history.First().Close orderby priceIndex descending select stock; int numberOfStocksToPick = (int)Math.Round(sortedByPriceIndex.Count() * 0.2); var highestPriceIndexStocks = sortedByPriceIndex.Take(numberOfStocksToPick); _rebalance = false; lastRebalance = Time; var symbols = (from x in highestPriceIndexStocks orderby x.ValuationRatios.PBRatio select x.Symbol).Take(30).ToList(); //Debug(Time + ": Succesfully chose " + ActiveSecurities.Count + " new stocks!"); return symbols; } public override void OnSecuritiesChanged(SecurityChanges changes) { foreach (var removed in changes.RemovedSecurities) { if (removed.Invested) { Liquidate(removed.Symbol); } } } public override void OnData(Slice slice) { if (Time > lastRebalance.AddMonths(6)) { _rebalance = true; } } } }