Overall Statistics
/*
 * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
 * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using QuantConnect.Data.Market;
using QuantConnect.Data.UniverseSelection;
using Newtonsoft.Json;

namespace QuantConnect.Algorithm.CSharp
{
	
    /// <summary>
    /// In this algortihm we show how you can easily use the universe selection feature to fetch symbols
    /// to be traded using the AddUniverse method. This method accepts a function that will return the
    /// desired current set of symbols. Return Universe.Unchanged if no universe changes should be made
    /// </summary>
    public class DropboxUniverseSelectionAlgorithm : QCAlgorithm
    {
    	public DateTime current_date;
    	List<OrderTicket> MyLimitOrders = new List<OrderTicket>();
        // the changes from the previous universe selection
        private SecurityChanges _changes = SecurityChanges.None;
        // only used in backtest for caching the file results
        private readonly Dictionary<DateTime, List<string>> _backtestSymbolsPerDay = new Dictionary<DateTime, List<string>>();
        public decimal _price;
		
        /// <summary>
        /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
        /// </summary>
        /// <seealso cref="QCAlgorithm.SetStartDate(System.DateTime)"/>
        /// <seealso cref="QCAlgorithm.SetEndDate(System.DateTime)"/>
        public override void Initialize()
        
        {
            // this sets the resolution for data subscriptions added by our universe
            UniverseSettings.Resolution = Resolution.Minute;
            UniverseSettings.Leverage = 2;            

            // set our start and end for backtest mode
            SetStartDate(2010, 1, 4);
            SetEndDate(2011, 10, 1);
			SetCash(100000);
			
			Chart plotter = new Chart("Plotter");
            plotter.AddSeries(new Series("SPY", SeriesType.Line, index:0));
            AddChart(plotter);
            
            // define a new custom universe that will trigger each day at midnight
            AddUniverse("my-dropbox-universe", Resolution.Daily, dateTime =>
            {
                const string liveUrl = @"https://www.dropbox.com/s/2az14r5xbx4w5j6/daily-stock-picker-live.csv?dl=1";
                const string backtestUrl = @"https://www.dropbox.com/s/zeiwihafw78qqq4/dataforqc2.csv?dl=1";
                var url = LiveMode ? liveUrl : backtestUrl;
                using (var client = new WebClient())
                {
                    // handle live mode file format n 
                    if (LiveMode)
                    {
                    	SetBlackList("OPK","AYR","CCD","KBIO");
            			var signals = GetSignal(checkdate(), 4);
                    	string[] stocks = new string[4];
                    	var count = 0;
                    	foreach (var stock in signals){
							stocks[count] = stock.Ticker;
							count++;
			            }
			            
			            return stocks;
                    	
                    	/*
                        // fetch the file from dropbox
                        var file = client.DownloadString(url);
                        // if we have a file for today, break apart by commas and return symbols
                        if (file.Length > 0) return file.ToCsv();
                        // no symbol today, leave universe unchanged
                        return Universe.Unchanged;
                        */
                    }

                    // backtest - first cache the entire file
                    if (_backtestSymbolsPerDay.Count == 0)//
                    {
                        // fetch the file from dropbox only if we haven't cached the result already
                        var file = client.DownloadString(url);

                        // split the file into lines and add to our cache
                        foreach (var line in file.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries))
                        {
                            var csv = line.ToCsv();
                            var date = DateTime.ParseExact(csv[0], "yyyyMMdd", null);
                            var symbols = csv.Skip(1).ToList();
                            _backtestSymbolsPerDay[date] = symbols;
                            //foreach (var symbol in symbols){
                            //	Console.Write(Time.ToString()+ " " +symbol);
                            //}
                        }
                    }

                    // if we have symbols for this date return them, else specify Universe.Unchanged
                    List<string> result;
                    if (_backtestSymbolsPerDay.TryGetValue(dateTime.Date, out result))
                    {
                        return result;
                    }
                    return Universe.Unchanged;
                }
            });
        }

        /// <summary>
        /// Stock data event handler
        /// </summary>
        /// <param name="data"></param>
        public void OnData(TradeBars data)
        {
        	
        	if (current_date == Time.Date) return;
        	
        	var percentage = 1m/4;
        	
        	if (Time.TimeOfDay < new TimeSpan(10, 30, 00)){
        		
        		
        		//THIS IS PART 1
	        	if (Time.TimeOfDay == new TimeSpan(9, 31, 00)){
	        		
		        	foreach (var symbol in _backtestSymbolsPerDay[Time.Date])
			        {
			        	_price = 0;
			        	_price = ((decimal)Securities[symbol].Price);
			        	
			        	if (_price != 0)
			        	{
				        	var quantity = (int)(double)(Portfolio.Cash/_price/4);
				        	var newTicket = LimitOrder(symbol, quantity, _price * .9975m);
					        MyLimitOrders.Add(newTicket);
					        //Log("New Limit Order: " + newTicket.Symbol.ToString() + " | $" + newTicket.Get(OrderField.LimitPrice).ToString("0.00"));
			        	}
			        }
	        	}
	        	
				
	        	if (Time.TimeOfDay == new TimeSpan(9, 40, 00)){

	        		var OrderTicketToUpdate = MyLimitOrders;
	        		
		        	foreach (var OrderTicketToCheck in OrderTicketToUpdate)
			        {
			        	if (OrderTicketToCheck != null){
				        	var _price = Securities[OrderTicketToCheck.Symbol].Close; 
				        	if (_price != 0)
				        	{
				        		if (OrderTicketToCheck.Status != OrderStatus.Filled){
									OrderTicketToCheck.Update(new UpdateOrderFields{LimitPrice = _price * .9992m});
									//Log("Updated Limit Price: " + OrderTicketToCheck.Symbol.ToString() + " | $" + (_price * .999m).ToString("0.00"));
				        		}
				        		else {
				        		//	Log("Order Filled: " + OrderTicketToCheck.Symbol.ToString());
				        		}
				        	}
			        	}
		    		}
	        	}
	        	
	        	
	        	if (Time.TimeOfDay == new TimeSpan(9, 52, 00)){

	        		var OrderTicketToUpdate = MyLimitOrders;
	        		
		        	foreach (var OrderTicketToCheck in OrderTicketToUpdate)
			        {
			        	if (OrderTicketToCheck != null){
				        	var _price = Securities[OrderTicketToCheck.Symbol].Close; 
				        	if (_price != 0)
				        	{
				        		if (OrderTicketToCheck.Status != OrderStatus.Filled){
									OrderTicketToCheck.Update(new UpdateOrderFields{LimitPrice = _price * 1.02m});
									//Log("Updated Limit Price to MARKET: " + OrderTicketToCheck.Symbol.ToString() + " | $" + (_price * 1.02m).ToString("0.00"));
				        		}
				        	}
			        	}
		    		}
	        	}
	        
	        	if (Time.TimeOfDay == new TimeSpan(10, 15, 00)){
					MyLimitOrders.Clear();
	        	}
	        	        
	        
	        
	        	
        	}
        	
        	if (Time.TimeOfDay > new TimeSpan(15, 55, 00)){
	        Liquidate();
	        }
	        if (Time.TimeOfDay > new TimeSpan(15, 59, 00)){
	        current_date = Time.Date;
	        
	        }
	            
        	//var timeout = Task.Delay(TimeSpan.FromSeconds(20));
        	//var work = Task.Run(() => {
	
	            // start fresh
	            
	
	            // reset changes
	            _changes = SecurityChanges.None;
        	//});
        	//Task.WaitAny(timeout, work);
        }

		/*
 		public override void OnEndOfDay(string symbol)
        {
		        Liquidate();
        }
		*/
		
        /// <summary>
        /// Event fired each time the we add/remove securities from the data feed
        /// </summary>
        /// <param name="changes"></param>
        public override void OnSecuritiesChanged(SecurityChanges changes)
        {
            // each time our securities change we'll be notified here
            _changes = changes;
        }
        
        public static void SetBlackList(params string[] tickers)
        {
            var joined = string.Join(",", tickers);
            using (var wc = new WebClient())
            {
                wc.DownloadString("ONLY IN LIVE" + joined);
            }
        }
        
        public static List<SignalStock> GetSignal(DateTime date, int count = 10)
        {
            using (var wc = new WebClient())
            {
                var str = wc.DownloadString(string.Format("ONLY IN LIVE", date.Year, date.Month, date.Day, count));
                return JsonConvert.DeserializeObject<List<SignalStock>>(str);
            }
        }
        
        private static DateTime checkdate()
        {
            if ((int)(DateTime.Now.DayOfWeek) != 1)
            {
                return DateTime.Now.AddDays(-1);
            }
            else
            {
                return DateTime.Now.AddDays(-3);
            }
        }
        
    }
    
    public class SignalStock
    {
        public string Ticker;
        public List<InsiderTransaction> Transactions;
        public double StockSignal;
        public StockDetails Details;
        public InsiderTransaction MainTransaction;
    }

    public class InsiderTransaction
    {
        public int? ExpertRank { get; set; }
        public DateTime Date { get; set; }
        public string OperationRatingString { get; set; }
        public string InsiderOperationType { get; set; }
        public string Ticker { get; set; }
        public string StockDisplayName { get; set; }
        public bool IsDirector { get; set; }
        public bool IsOfficer { get; set; }
        public string OfficerName { get; set; }
        public bool IsTenPercentOwner { get; set; }
        public decimal? Value { get; set; }
        public bool IsInformative { get; set; }
        public long? MarketCap { get; set; }
        public long InsiderOperationId { get; set; }
        public string InsiderName { get; set; }
        public double Signal { get; set; }
    }


    public class StockDetails
    {
        public string yLow;
        public string ticker { get; set; }
        public string pe { get; set; }
        public string marketCap { get; set; }
        public string openPrice { get; set; }
        public string eps { get; set; }
        public string divPerYield { get; set; }
        public string fiscalDiv { get; set; }
        public string beta { get; set; }
        public string shares { get; set; }
        public string market { get; set; }
        public string instOwn { get; set; }
        public string low { get; set; }
        public string high { get; set; }
        public string price { get; set; }
        public string yHigh { get; set; }
        public string range { get; set; }
        public string changeAmount { get; set; }
        public string changePercent { get; set; }
        public string average { get; set; }
        public string volume { get; set; }
        public string volumeAndAvg { get; set; }
        public string prevClose { get; set; }
        public string bid { get; set; }
        public string ask { get; set; }
        public string oneYearTargetEst { get; set; }
        public DateTime? nextEarningDate { get; set; }
        public string daysRange { get; set; }
        public string range52Weeks { get; set; }
        public string low52Weeks { get; set; }
        public string high52Weeks { get; set; }
        public string avgVol3Months { get; set; }
    }
}