Overall Statistics
using System;
using System.Text.RegularExpressions;

namespace QuantConnect
{
    /// <summary>
    /// QC University algorithm to demonstrate split and dividend events 
    /// </summary>
    public class QCUTotalReturnsAlgorithm : QCAlgorithm
    {
    	private int sliceCount;
		private int barCount;
		private int displayBarCount;
		private int tickCount;
		private int displayTicks;
		private int securitiesToPurchase;
    	
    	private class SecurityParam {
    		public string symbol = "";
    		public decimal percentInvestment = 0;
    		public bool purchased = false;
    		public bool displayBadQuantity = true;
    	}
    	private List<SecurityParam> my_securities = new List<SecurityParam>();
    	
        /// <summary>
        /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm.
        /// All algorithms must initialized.
        /// </summary>
        public override void Initialize()
        {
    		Debug("Initialize:+");
			sliceCount = 0;
			barCount = 0;
			displayBarCount = 10;
			tickCount = 0;
			displayTicks = 2;
			securitiesToPurchase = 0;

			string securitiesParamStrg = GetParameter("securities");
			Debug("Initialzie: securitiesParamStrg=" + securitiesParamStrg);
			if (securitiesParamStrg != null)
			{
				Debug("Initialzie: securitiesParamStrg=" + securitiesParamStrg);
				string[] securityInfo = Regex.Split(securitiesParamStrg, ",");
				foreach (var securityStrg in securityInfo)
				{
					// Debug("Initialize: securityStrg=" + securityStrg);
					Match match = Regex.Match(securityStrg, @"(\w+):(\d+)%");
					//Debug("Initialize: match=" + match + " match.Groups.Count=" + match.Groups.Count);
					if (match.Groups.Count >= 2)
					{
						SecurityParam param = new SecurityParam();
						param.symbol = match.Groups[1].Captures[0].Value;
						if (match.Groups.Count >= 3)
						{
							param.percentInvestment = Decimal.Parse(match.Groups[2].Captures[0].Value) / 100m;
							securitiesToPurchase += 1;
						}
						else
						{
							param.percentInvestment = 0;
						}
						Debug(string.Format("Initialize: symbol={0} percentInvestment={1}",
							param.symbol, param.percentInvestment));
						my_securities.Add(param);
					}
				}
			}
			if (securitiesToPurchase == 0)
			{	// Defaults
				SecurityParam param = new SecurityParam();
				param.symbol = "SPY";
				param.percentInvestment = 0.25m;
				my_securities.Add(param);
				Debug(string.Format("Initialize: {0} {1}", param.symbol, param.percentInvestment));
				param = new SecurityParam();
				param.symbol = "VCLT";
				param.percentInvestment = 0.25m;
				my_securities.Add(param);
				securitiesToPurchase = 2;
				Debug(string.Format("Initialize: {0} {1}", param.symbol, param.percentInvestment));
			}
			
            SetStartDate(2010, 1, 1);  //Set Start Date
            //SetStartDate(1999, 01, 01);  //Set Start Date
            //SetStartDate(DateTime.Now.Date.AddDays(-10));  //Set Start Date
            SetEndDate(2010, 1, 5);  //Set End Date
            //SetEndDate(DateTime.Now.Date.AddDays(-1));    //Set End Date
            SetCash(10000);             //Set Strategy Cash

            // Add the securities half Tick and half Minute Resolution
            Resolution resolution = Resolution.Tick;
            foreach (var security in my_securities)
            {
              AddSecurity(SecurityType.Equity, security.symbol, resolution);
              Securities[security.symbol].SetDataNormalizationMode(DataNormalizationMode.TotalReturn);
            }
            Debug("Initialize:-");
        }

		public override void OnData(Slice data)
		{
			//Debug("OnData(Slice)");
			sliceCount += 1;
            if (securitiesToPurchase > 0)
            {
				foreach (SecurityParam security in my_securities
					.Where(x => !x.purchased 
								&& (x.percentInvestment > 0)
								&& (data.Bars.ContainsKey(x.symbol) || data.Ticks.ContainsKey(x.symbol))))
				{
					Debug(string.Format("OnData-Slice: {0} Price={1} securitiesToPurchase={2} security.purchased={3} security.percentInvestment={4}",
							security.symbol, Securities[security.symbol].Price,
							securitiesToPurchase, security.purchased, security.percentInvestment));
					#if true
						SetHoldings(security.symbol, security.percentInvestment);
						var quantity = Securities[security.symbol].Holdings.Quantity;
						Debug(string.Format("OnData-Slice: Purchased Stock {0} {1}% quantity={2}",
							security.symbol, security.percentInvestment, quantity));
					#else
						var quantity = CalculateOrderQuantity(security.symbol, (double)security.percentInvestment);
						OrderTicket ticket = MarketOrder(security.symbol, quantity, false, "");
						Debug(string.Format("OnData-Slice: Purchased Stock {0} {1}% ticket={2}",
							security.symbol, security.percentInvestment, ticket));
					#endif
					security.purchased = true;
					securitiesToPurchase -= 1;
				}
            }

			// When !Resolution.Tick such as Resolution.Minute data.Bars
			// passed in the Slice
			foreach (var kvp in data.Bars)
			{
				Symbol symbol = kvp.Key;
				TradeBar bar = kvp.Value;
				barCount += 1;
				if (displayBarCount > 0)
				{
					displayBarCount -= 1;
					Debug(string.Format("OnData-Slice: {0} time={1} open={2} high={3} low={4} close={5} volume={6} Value={7}",
						bar.Symbol, bar.Time, bar.Open, bar.High, bar.Low, bar.Close, bar.Volume, bar.Value));
				}
			}

			// Resolution.Tick the data will procided in data.Ticks
			foreach (var kvp in data.Ticks)
			{	// Only occurs if Resolution.Tick
				tickCount += 1;
				if (displayTicks > 0)
				{
					Debug("OnData-Slice: ticks count=" + data.Ticks.Count);
					displayTicks -= 1;
					int innerDisplay = 5;
					Symbol symbol = kvp.Key;
					List<Tick> ticks = kvp.Value;
					foreach (var tick in ticks)
					{
						if (innerDisplay > 0) {
							innerDisplay -= 1;
							Debug(string.Format("OnData-Slice: symbol={0} s={1} lp={2} q={3} bp={4} ap={5} t={6}", symbol, tick.Symbol,
								tick.LastPrice, tick.Quantity, tick.BidPrice, tick.AskPrice, tick.Time));
						} else {
							break;
						}
					}
				}
			}
		}
		
        public void OnData(Dividends data) // update this to Dividends dictionary
        {
        	foreach(var key in data.Keys)
			{
			#if false
				var dividend = data[key];
				Debug(string.Format("OnData-Dividends: {0} {1} - {2} - {3} - {4}",
					dividend.Symbol, dividend.Time.ToString("o"), dividend.Distribution.ToString("C"),
					Portfolio.Cash, Portfolio[key].Price.ToString("C")));
            #endif
			}
        }

        public void OnData(Splits data)
        {
        	foreach(var key in data.Keys)
        	{
	            var split = data[key];
    	        Debug(string.Format("OnData-Splits: {0} {1} - {2} - {3} - {4} - {5}",
    	        	split.Symbol, split.Time.ToString("o"), split.SplitFactor, Portfolio.Cash,
    	        	Portfolio[key].Quantity, Portfolio[key].Price.ToString("C")));
        	}
        }
        
        public override void OnEndOfAlgorithm()
        {
			Debug(string.Format("OnEndOfAlgorithm: sliceCount={0} tickCount={1} barCount={2}",
				sliceCount, tickCount, barCount));
        }
    }
}