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