Overall Statistics
        using System;
using System.Linq;
using QuantConnect.Data;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Util;
using System.Reflection;

namespace QuantConnect.Algorithm.CSharp
{
    /// <summary>
    /// This algorithm shows how to grab symbols from an external api each day
    /// and load data using the universe selection feature. In this example we
    /// define a custom data type for the NYSE top gainers and then short the 
    /// top 2 gainers each day
    /// </summary>
    public class CustomDataUniverseAlgorithm : QCAlgorithm
    {
        private SecurityChanges _changes;
        static readonly decimal EqualWeightPercentage = 1m/3;
        DateTime lastTradeTime;
        Security _security;

        public override void Initialize()
        {
        	SetBrokerageModel(BrokerageName.TradierBrokerage, AccountType.Cash);
        	
            UniverseSettings.Resolution = Resolution.Minute;

            SetStartDate(2016, 02, 01);
            SetEndDate(DateTime.Now);

            SetCash(2000);

            AddSecurity(SecurityType.Equity, "SPY", Resolution.Daily);
            SetBenchmark("SPY");

            // add a custom universe data source (defaults to usa-equity)
            AddUniverse<NyseTopGainers>("universe-nyse-top-gainers", Resolution.Minute, data =>
            {
                // define our selection criteria
                return from d in data
                       // pick top 2 gainers to bet against
                       where d.TopGainersRank <= 2
                       select d.Symbol;
            });
        }

        public void OnData(TradeBars data)
        {
        	if (Time - lastTradeTime.Date < TimeSpan.FromDays(1))
        	{
        		return;
        	}
        	lastTradeTime = Time;
        	            foreach (var security in _changes.AddedSecurities)
            {
            	_security = security;
            	Log("" + _security.Symbol);
            }

        	
        	var equalWeightedPortfolioSize = Portfolio.TotalPortfolioValue/3;
        	var shareCount = CalculateOrderQuantity(_security.Symbol, EqualWeightPercentage);
        	if (!Portfolio.Invested && _security.Symbol != "SPY")
                {
        		MarketOrder(_security.Symbol, shareCount, tag: "Order Target Value: $" + Math.Round(equalWeightedPortfolioSize, 2));
                }
        	//Log("Enter  " + _security.Symbol + " at " + _security.Close);
        	MarketOnCloseOrder(_security.Symbol, -shareCount);
        	
        	var settledCash = Portfolio.CashBook["USD"].Amount;
            // you can access the unsettled fund using the UnsettledCashBook
            var unsettledCash = Portfolio.UnsettledCashBook["USD"].Amount;
        	
        }

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

            /*foreach (var security in changes.RemovedSecurities)
            {
            	
                // liquidate securities that have been removed
                if (security.Invested)
                {
                    Liquidate(security.Symbol);
                    Log("Exit " + security.Symbol + " at " + security.Close);
                }
            }*/
        }
        
         /*public override void OnEndOfDay()
        {
            // at the end of each day log the state of our settled and unsettled cashbooks
            Log(string.Empty);
            Log("-------------------"+Time.Date.ToShortDateString()+"-------------------");
            Log("SETTLED::");
            var settled = Portfolio.CashBook.ToString();
            foreach (var line in settled.Split('\n'))
            {
                Log("    " + line);
            }
            Log(string.Empty);
            Log(string.Empty);
            Log("UNSETTLED::");
            var unsettled = Portfolio.UnsettledCashBook.ToString();
            foreach (var line in unsettled.Split('\n'))
            {
                Log("    " + line);
            }
        }*/


        /// <summary>
        /// Custom data type that uses the wall street journal's top 100 nyse gainers
        /// html page as a live data source, and a csv file that contains the top 10
        /// nyse gainers since the beginning of 2009 until 2015/10/19
        /// </summary>
        public class NyseTopGainers : BaseData
        {
            public int TopGainersRank;

            private int count;
            public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLiveMode)
            {

                    return new SubscriptionDataSource(@"http://www.wsj.com/mdc/public/page/2_3021-gainnyse-gainer.html", SubscriptionTransportMedium.RemoteFile);
                    return new SubscriptionDataSource(@"http://www.wsj.com/mdc/public/page/2_3021-gainnnm-gainer.html?mod=mdc_pastcalendar", SubscriptionTransportMedium.RemoteFile);
               
            }

            public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLiveMode)
            {

                // parse the html into a symbol

                if (!line.StartsWith(@"<a href=""/public/quotes/main.html?symbol="))
                {
                    // we're only looking for lines that contain the symbols
                    return null;
                }

                var lastCloseParen = line.LastIndexOf(")", StringComparison.Ordinal);
                var lastOpenParen = line.LastIndexOf("(", StringComparison.Ordinal);
                if (lastOpenParen == -1 || lastCloseParen == -1)
                {
                    return null;
                }

                var symbolString = line.Substring(lastOpenParen + 1, lastCloseParen - lastOpenParen - 1);
                return new NyseTopGainers
                {
                    Symbol = Symbol.Create(symbolString, SecurityType.Equity, Market.USA),
                    Time = date,
                    // the html has these in order, so we'll keep incrementing until a new day
                    TopGainersRank = ++count
                };
            }
        }
    }
}