Overall Statistics
using QuantConnect.Data.Consolidators;
using QuantConnect.Orders;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Algorithm;
using QuantConnect.Data.Market;
using QuantConnect.Data;
using QuantConnect.Securities;
namespace QuantConnect 
{   
    /*
    *   Basics for getting ES mini future prices of the most current expiry.
    */
    public class ESMiniFutureAlgorithm : QCAlgorithm
    {
//        var futureGold = AddFuture(Futures.Metals.Gold);

		private const string RootSP500EMini = Futures.Indices.SP500EMini;
        public Symbol SP500EMini = QuantConnect.Symbol.Create(RootSP500EMini, SecurityType.Future, Market.USA);

        //Initialize the data and resolution you require for your strategy:
        public override void Initialize()
        {
            //Initialize
            SetStartDate(2017, 1, 1);         
            //SetEndDate(2017, 6, 18); 
            SetCash(50000);
            SetWarmup(TimeSpan.FromDays(5));
            var futureSP500EMiniMinute = AddFuture(RootSP500EMini, Resolution.Minute);
            futureSP500EMiniMinute.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(190));
        }
        
        protected readonly Dictionary<Symbol, long> DayVolume = new Dictionary<Symbol, long>();
        protected DateTime DayVolumeDate = new DateTime(1900, 1, 1);
        protected Symbol SymbolMaxVolume = null;
        
//		protected String lastSliceBars = "";
        protected String lastFutsBars = "";

		protected void UpdateDayVolumeFromSlice(Slice slice)
		{
			foreach (TradeBar bar in slice.Bars.Values)
   			{
   				DayVolume[bar.Symbol] = (DayVolume.Keys.Contains(bar.Symbol) ? DayVolume[bar.Symbol] : 0) + bar.Volume;
   			}
		}

		protected String lastBarsFuts = "-";
		
     	public override void OnData(Slice slice)
     	{
        	String barsFuts = "";
        	if (slice.Bars.Count > 0)
        	{
        		barsFuts += "Bars";
        	}
        	if (slice.FutureChains.Count > 0)
        	{
        		barsFuts += "Futs";
        	}
        	if (lastBarsFuts != barsFuts)
        	{
        		Log(barsFuts);
        		lastBarsFuts = barsFuts;
        	}
     	}

     	public void OnData2(Slice slice)
        {
        	
			// String sliceBars = String.Join(", ", slice.Bars.Keys);
   //     	if (!lastSliceBars.Equals(sliceBars)) 
   //     	{
   //     		Log("SliceBars: " + sliceBars);
   //     		lastSliceBars = sliceBars;
   //     	}
   			if (Time.Date != DayVolumeDate)
   			{
   				Log("new day: " + (slice.Bars.Count > 0 ? "bars " : " ") + (slice.FutureChains.Count > 0 ? "futs" : "") );
   				if (DayVolume.Keys.Count > 0)
	   			{
	   				var NewSymbolMaxVolume = DayVolume.OrderByDescending( x => x.Value ).First();
	   				if (!NewSymbolMaxVolume.Key.Equals(SymbolMaxVolume))
	   				{
	   					SymbolMaxVolume = NewSymbolMaxVolume.Key;
	   					Log(String.Join(",",  DayVolume.ToDictionary(x => x.Key.Value, x => x.Value)) + " -- Selected " + SymbolMaxVolume.Value);
	   				}
	   				DayVolume.Clear();
	   			}
   				DayVolumeDate = Time.Date;
   			}
   			UpdateDayVolumeFromSlice(slice);
        	String futsBars = String.Empty;
   	        foreach (FuturesChain chain in slice.FutureChains.Values)
   	        {
   	        	foreach (FuturesContract fc in chain.Contracts.Values)
   	        	{
   	        		if (slice.Bars.Keys.Contains(fc.Symbol))
   	        		{
   	        			futsBars += fc.Symbol.Value + "[" + fc.Expiry + " " + fc.Symbol.ID + "] ";
   	        			// TradeBar bar = slice.Bars[fc.Symbol];
   	        			// if (bar.Period >= OneDay)
   	        			// {
   	        			// 	Log( fc.Symbol.Value + ": " + bar.Volume);
   	        			// }
   	        		}
   	        	}
   	        }
   	        if (futsBars != String.Empty && !lastFutsBars.Equals(futsBars))
   	        {
   	        	Log("FutsBars: "+ futsBars);
   	        	lastFutsBars = futsBars;
   	        }
        }
           
        // Fire plotting events once per day:
        public override void OnEndOfDay() 
        {
            //Console.WriteLine(Time + " End of day");
        }
    }
}