Overall Statistics
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic; 
using QuantConnect.Securities;  
using QuantConnect.Models;   

namespace QuantConnect { 
    
    public partial class QCUWeatherBasedRebalancing : QCAlgorithm
    {
        //Initialize: Storage for our custom data:
        //Source: http://www.wunderground.com/history/
        //Make sure to link to the actual file download URL if using dropbox.
        //private string url = "https://www.dropbox.com/s/txgqzv2vp5lzpqc/10065.csv";
        private Weather yesterday;
        private int rebalanceFrequency = 2, tradingDayCount = 0;
        
        ///<summary>
        /// Initialize our algorithm:
        ///</summary>
        public override void Initialize()
        {
            SetStartDate(2013, 1, 1);         
            SetEndDate(DateTime.Today.AddDays(-1)); 
            SetCash(25000);
            AddSecurity(SecurityType.Equity, "SPY", Resolution.Minute);
            
            // KNYC is NYC Central Park. Find other locations at
            // https://www.wunderground.com/history/
            AddData<Weather>("KNYC", Resolution.Daily);
        }
        
        //Save the instance of the weather.
        public void OnData(Weather data)
        {
            yesterday = data;
        }
        
        ///<summary>
        /// When we have a new event trigger, buy some stock:
        ///</summary>
        public void OnData(TradeBars data) 
        {   
            //Rebalance every 10 days:
            if (tradingDayCount >= rebalanceFrequency) 
            {   
                //Scale from -5C to +25C :: -5C == 0, +25C = 100% invested.
                if (yesterday != null) {
                    decimal fraction = (yesterday.MinC + 5m) / 30m;
                    SetHoldings("SPY", fraction); 
                    tradingDayCount = 0;
                } 
            }
        }
        
        ///<summary>
        /// After each trading day
        ///</summary>
        public override void OnEndOfDay() {
            tradingDayCount++;
        }
    }
    
    /// <summary>
    /// Weather based rebalancing
    /// </summary>
    public class Weather : BaseData
    {
        public decimal MaxC = 0;
        public decimal MinC = 0;
        public string errString = "";

        public override SubscriptionDataSource GetSource(SubscriptionDataConfig config, DateTime date, bool isLive)
        {
            var source = string.Format(
                "https://www.wunderground.com/history/airport/{0}/{1}/1/1/CustomHistory.html?dayend=31&monthend=12&yearend={1}&format=1",
                config.Symbol, date.Year);

            // Uncomment this line if you want to use the dropbox file (not updated)
			//source = "https://www.dropbox.com/s/txgqzv2vp5lzpqc/10065.csv";
        
            return new SubscriptionDataSource(source, SubscriptionTransportMedium.RemoteFile);
        }

        public override BaseData Reader(SubscriptionDataConfig config, string line, DateTime date, bool isLive)
        {
            if (string.IsNullOrWhiteSpace(line) || char.IsLetter(line[0])) return null;
            
            var data = line.Split(',');

            return new Weather()
            {
                Time = DateTime.Parse(data[0]).AddHours(20), // Make sure we only get this data AFTER trading day - don't want forward bias.
                Symbol = config.Symbol,
                MaxC = Convert.ToDecimal(data[1]),
                Value = Convert.ToDecimal(data[2]),
                MinC = Convert.ToDecimal(data[3]),
            };
        }
    }
}