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;
        // 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>>();

        /// <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)"/>
        /// <seealso cref="QCAlgorithm.SetCash(decimal)"/>
        public override void Initialize()
        {
            // this sets the resolution for data subscriptions added by our universe
            UniverseSettings.Resolution = Resolution.Minute;

            // set our start and end for backtest mode
            SetStartDate(2012, 7, 15);
            SetEndDate(2012, 8, 02);

            // define a new custom universe that will trigger each day at midnight
            AddUniverse("my-dropbox-universe", Resolution.Minute, 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/kzo2kdu2v7q7qc1/dataforqc.csv?dl=1";
                var url = LiveMode ? liveUrl : backtestUrl;
                using (var client = new WebClient())
                {
                    // handle live mode file format n 
                    if (LiveMode)
                    {
                        // 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 (Time.TimeOfDay.TotalHours > 15.9){
	        Liquidate();
	        }
	            
	        if (_changes == SecurityChanges.None || current_date == Time.Date) return;
        	
        	//var timeout = Task.Delay(TimeSpan.FromSeconds(20));
        	//var work = Task.Run(() => {
	
	            // start fresh
	            
	            var percentage = 1m/data.Count;
	            foreach (var tradeBar in data.Values)
	            {
	            	SetHoldings(tradeBar.Symbol, percentage);            		
	            	
	
	            }
	
	            // reset changes
	            _changes = SecurityChanges.None;
	            current_date = Time.Date;
        	//});
        	//Task.WaitAny(timeout, work);
        }

 		public override void OnEndOfDay(string symbol)
        {
	
        }

        /// <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("http://signalbackend.azurewebsites.net/Signal/SetBlackList?tickers=" + joined);
            }
        }
        
        public static List<SignalStock> GetSignal(DateTime date, int count = 10)
        {
            using (var wc = new WebClient())
            {
                var str = wc.DownloadString(string.Format("http://signalbackend.azurewebsites.net/Signal/Signal?year={0}&month={1}&day={2}&count={3}", date.Year, date.Month, date.Day, count));
                return JsonConvert.DeserializeObject<List<SignalStock>>(str);
            }
        }
        
    }
    
    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; }
    }
}