Overall Statistics
namespace QuantConnect.Algorithm.CSharp
{
	using System.Collections.Concurrent;
	using Newtonsoft.Json;

    public class DoubleVolumeBuyAtClose : QCAlgorithm
    {
    	private int stocksInBackTest = 100;
    	private int datesOfBackTest = 40;
    	public int startingCash = 10000;
    	
    	private string scheduleSymbol = "SPY";
    	
    	public int counter = 0;
    	
    	private int serialized = 0;
    	
    	private readonly ConcurrentDictionary<Symbol, RollingWindow<decimal>> historicalVolumes = new ConcurrentDictionary<Symbol, RollingWindow<decimal>>();

		private List<Symbol> dailySymbols = new List<Symbol>();

        public override void Initialize()
        {
        	var endDate = new DateTime(2020, 3, 6); //Friday
        	
            SetStartDate(endDate.AddDays(datesOfBackTest * -1));  
            SetEndDate(endDate);  
            SetCash(startingCash);

			AddUniverse(CoarseSelectionFilter);
			
			UniverseSettings.Resolution = Resolution.Minute;
			
			var spy = this.AddEquity(scheduleSymbol).Symbol;
            
			AddUniverse(CoarseSelectionFilter);
			
			//SetBrokerageModel(BrokerageName.OandaBrokerage, AccountType.Cash);
			
			UniverseSettings.Resolution = Resolution.Minute;
			
			Schedule.On(DateRules.EveryDay(spy), TimeRules.BeforeMarketClose(spy, 10), BeforeClose);
        }
	    
	    public void BeforeClose()
	    {
		    foreach(var selection in dailySymbols) 
    		{
    			if (!historicalVolumes.ContainsKey(selection)) 
    			{ 
    				var history = History(selection, 20, Resolution.Daily);
    				
    				historicalVolumes[selection] = new RollingWindow<decimal>(20);
    				
    				foreach(var h in history) 
    				{
    					historicalVolumes[selection].Add(h.Volume);
    				}
    			}
    		
    			var window = historicalVolumes[selection];
    			
    			if (window.IsReady)
    			{
    				var sec = this.Securities[selection];
    				
    				var average = window.Skip(1).Average(f=>f);

					var resolution = sec.Resolution;

					var open = sec.Open;
    				var current = sec.Price;
    				var volume = sec.Volume;
    				
    				if ((average * 3) < volume && open < current) 
    				{
    					var h = History(selection, 30, Resolution.Daily);
	    				var averageSpan = h.Select(f=> Math.Abs(f.Open - f.Close)).Average();
	    				
		    			var takeProfit =  sec.Price + averageSpan;
		    			var stopLosss = sec.Price - averageSpan;
		    			
		    			var position = Math.Ceiling((averageSpan * 4) / sec.Price) ;
		    			
	    				MarketOrder(sec.Symbol, position);
    					StopLimitOrder(sec.Symbol, position * -1, stopLosss, takeProfit);
    				}
    			}
    			
    			window.Add(this.Securities[selection].Volume);
    		}
	    }


		public IEnumerable<Symbol> CoarseSelectionFilter(IEnumerable<CoarseFundamental> universe)
    	{
    		universe = universe.Where(f=> f.Price > 100 && f.DollarVolume > 10000000 && f.Price < 600).Take(stocksInBackTest);
    	
			dailySymbols = universe.Select(f=>f.Symbol).ToList();
			
    		return dailySymbols;
        }
    }
}