Overall Statistics
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Indicators;
using QuantConnect.Data;
using System.Linq;


namespace QuantConnect.Algorithm.CSharp
{
    public class BasicTemplateAlgorithm : QCAlgorithm
    {
        int myUniverseCount = 0;
        private const int Count = 50; //NUMBER OF STOCKS FOR UNIVERSE TO SELECT

        private SecurityChanges _changes = SecurityChanges.None;
        private static readonly ConcurrentDictionary<Symbol, SelectionData> _averages = new ConcurrentDictionary<Symbol, SelectionData>();
        private class SelectionData
        {
            public readonly StandardDeviation mySTD;

            public SelectionData(QCAlgorithm algorithm, Symbol symbol)
            {
                mySTD = new StandardDeviation(20);

                algorithm.AddSecurity(SecurityType.Equity, symbol);
                var history = algorithm.History(symbol, 20);
                algorithm.RemoveSecurity(symbol);
                foreach (TradeBar tradeBar in history)
                {
                    mySTD.Update(tradeBar.EndTime, tradeBar.Close);
                }
                
            }
            public decimal mySTDValue(decimal price)
            {
                return mySTD / price;
            }

            public bool Update(DateTime time, decimal value)
            {
                return mySTD.Update(time, value);
            }
        }


        public override void Initialize()
        {
            SetStartDate(2015, 12, 01);
            //SetEndDate(2009, 6, 1);
            SetCash(25000);
            UniverseSettings.Resolution = Resolution.Minute;
            SetWarmup(TimeSpan.FromMinutes(20));

            AddUniverse(coarse =>
            {
                var topVolume = from cf in coarse
                                where cf.Volume >= 100000
                                select cf;
                return (from cf in topVolume
                        let avg = _averages.GetOrAdd(cf.Symbol, sym => new SelectionData(this, cf.Symbol))
                        where avg.Update(cf.EndTime, cf.Price)
                        orderby avg.mySTDValue(cf.Price) descending
                        select cf.Symbol).Take(Count);
            });
            
        }

        public void OnData(TradeBars data)
        {
            _changes = SecurityChanges.None;
        }

        public override void OnSecuritiesChanged(SecurityChanges changes)
        {
            _changes = changes;
        }
        
    }
}