Overall Statistics
//Copyright HardingSoftware.com, granted to the public domain.
//Use entirely at your own risk.
//Custom algorithm development: warrencharding@yahoo.com.
//Do not remove this copyright notice.
using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Data.Market;
using QuantConnect.Data.UniverseSelection;

namespace QuantConnect.Algorithm.CSharp
{
    public class Change : QCAlgorithm
    {
        SecurityChanges securityChanges = SecurityChanges.None;
		List<string> tickers=new List<string>();
        public override void Initialize()
        {
            UniverseSettings.Resolution = Resolution.Daily;

            SetStartDate(2012, 8, 23);
            SetEndDate(2017, 8, 23);
            SetCash(50000);

            AddUniverse(coarse =>
            {
            	return (from stock in coarse
            			orderby stock.DollarVolume descending  
            			select stock.Symbol).Take(10);
            });
        }

        public void OnData(TradeBars data)
        {
        	foreach (string ticker in tickers)
            {
                if (Portfolio[ticker].Invested)
                {
                    Liquidate(ticker);
                }
            }
			foreach (var security in securityChanges.RemovedSecurities)
            {
                tickers.Remove(security.Symbol);
            }
            foreach (var security in securityChanges.AddedSecurities)
            {
                tickers.Add(security.Symbol);
            }
            securityChanges = SecurityChanges.None;


            List<StockData> changers=new List<StockData>();
            int period=3;
            foreach (string ticker in tickers)
            {
            	StockData stockData=new StockData();
            	TradeBar[] bars=History(ticker,period,Resolution.Daily).ToArray();
            	decimal[] closes=bars.Select(x=>x.Close).ToArray();
            	if (bars!=null && bars.Length==period)
            	{
	            	stockData.Ticker=ticker;
	            	stockData.Changes1=ChangesPercent(closes);
	            	stockData.Changes2=Changes(stockData.Changes1);
	            	stockData.Fitness=stockData.Changes2[0];
	            	if (stockData.Changes1.Last()>0)
	            	{
	            		stockData.Fitness=-1000;
	            	}
	            	changers.Add(stockData);
            	}
            }
            List<StockData> sortedChangers = changers.OrderByDescending(x=>x.Fitness).Take(2).ToList();
   
            foreach (var security in sortedChangers)
            {
				SetHoldings(security.Ticker,1.0m/(decimal)sortedChangers.Count);
            }
        }

        public override void OnSecuritiesChanged(SecurityChanges changes)
        {
            securityChanges = changes;
        }
        
        public class StockData
        {
        	public string Ticker;
        	public decimal[] Changes1;
        	public decimal[] Changes2;
        	public decimal Fitness;
        }
        
        public static decimal[] Changes(decimal[] values)
        {
            List<decimal> lOut = new List<decimal>();
            for (int i = 0; i < values.Length - 1; i++)
            {
                lOut.Add(values[i + 1] - values[i]);
            }
            return lOut.ToArray();
        }

        public static decimal[] ChangesPercent(decimal[] values)
        {
            List<decimal> lOut = new List<decimal>();
            for (int i = 0; i < values.Length - 1; i++)
            {
                lOut.Add((values[i + 1] - values[i]) / values[i]);
            }
            return lOut.ToArray();
        }
    }
}