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


namespace QuantConnect.Algorithm.CSharp
{

    public class InspiriAlgorithm : QCAlgorithm
    {  	
		//region "Variables"
		private const decimal minPrice = 25;
		private const decimal minVolume = 500000;
		private const decimal tpPercent = 1.01m;
                
        // dictionary to easily access SymbolData class parameters
		private readonly Dictionary<Symbol, SymbolData> Data = new Dictionary<Symbol, SymbolData>();

        private SecurityChanges sChanges = SecurityChanges.None;
		
        public override void Initialize()
        {
            UniverseSettings.Resolution = Resolution.Minute;
            
            SetStartDate(2015, 11, 25);
            SetEndDate(2015, 11, 30);
            SetCash(10000);
            SetWarmup(15);
            
            AddUniverse(coarse =>
            {
                return (from cf in coarse
                        where cf.Price > minPrice
              			where cf.Volume > minVolume
              			orderby cf.Price descending
                        select cf.Symbol).Take(250);
            });
        }
        

        public void OnData(TradeBars data)
        {
        	foreach (var Stock in Data.Values)
        	{
        		if (data.ContainsKey(Stock.Symbol)) return;
            	if (IsWarmingUp) return;   		
            	
				if ( Portfolio.Count < 2)
            	{
            		
                	if ( Stock.lastMinute[1].High < Stock.hSMA && Stock.iRSI < 5 )
                	{
                	    Log("BUY  >> " + Stock.Security.Price);
                	    SetHoldings(Stock.Symbol, 0.5m);
                	    var takeProfit = Stock.Security.Price*tpPercent;
                	    LimitOrder(Stock.Symbol, - Stock.Quantity, takeProfit);
                	}
            	}

            	if (Stock.Quantity > 0 && Stock.lastMinute[1].High >= Stock.hSMA)
            	{
            	    Log("SELL >> " + Stock.Security.Price);
            	    Liquidate(Stock.Symbol);    
            	}
        	}	

        }

        public override void OnSecuritiesChanged(SecurityChanges changes)
    	{
    		sChanges = changes;
        	foreach (var removed in changes.RemovedSecurities)
        	{
            	if (removed.Invested)
            	{
                	Liquidate(removed.Symbol);
            	}
        	}

            foreach (var added in changes.AddedSecurities)
            {
                Data.Add(added.Symbol, new SymbolData(added.Symbol, this));
            }
    	}
    }

    class SymbolData
	{
	  	public string Symbol;
  		private const int hPeriods = 15;
		private const int rsiPeriods = 15;
		public int rollingWindowSize = 1;
		
		public readonly Security Security;
		public int Quantity
    	{
        	get { return Security.Holdings.Quantity; }
    	}

	    public readonly Identity Close;
		
	 	public readonly SimpleMovingAverage hSMA;
		public readonly RelativeStrengthIndex iRSI;
		public readonly RollingWindow<TradeBar> lastMinute;

  		public SymbolData(string symbol, QCAlgorithm algorithm)
		{
  	   		Symbol = symbol;
    		Security = algorithm.Securities[symbol];
        	Close = algorithm.Identity(symbol);
    		hSMA = algorithm.SMA(symbol, hPeriods, Resolution.Minute, Field.High);
        	iRSI = algorithm.RSI(symbol, rsiPeriods, MovingAverageType.Simple, Resolution.Minute);
        	lastMinute = new RollingWindow<TradeBar>(rollingWindowSize);;
    	}
    	
    	public bool IsReady
		{
            get { return Close.IsReady && hSMA.IsReady && iRSI.IsReady && lastMinute.IsReady; }
        }
	}
}