Overall Statistics
Total Trades
580
Average Win
0.55%
Average Loss
-0.26%
Compounding Annual Return
19.943%
Drawdown
19.500%
Expectancy
0.854
Net Profit
97.592%
Sharpe Ratio
1.062
Loss Rate
40%
Win Rate
60%
Profit-Loss Ratio
2.08
Alpha
0
Beta
0
Annual Standard Deviation
0.125
Annual Variance
0.016
Information Ratio
0
Tracking Error
0
Treynor Ratio
0
Total Fees
$0.00
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 decimal fraction;
        private int rebalanceFrequency = 2, tradingDayCount = 0;
        private Symbol symbol = QuantConnect.Symbol.Create("CORNUSD", SecurityType.Cfd, Market.Oanda);

        ///<summary>
        /// Initialize our algorithm:
        ///</summary>
        public override void Initialize()
        {
            SetStartDate(2013, 1, 1);         
            SetEndDate(DateTime.Today.AddDays(-1)); 
            SetCash(25000);
			SetBenchmark(time => 25000);

			SetBrokerageModel(BrokerageName.OandaBrokerage);

            AddCfd(symbol, 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)
        {
        	//Scale from -5C to +25C :: -5C == 100%, +25C = 0% invested
            fraction = -(data.MinC + 5m) / 30m;
            Plot("Weather", "Scale", fraction);
        }
        
        ///<summary>
        /// When we have a new event trigger, buy some stock:
        ///</summary>
        public void OnData(TradeBars data) 
        {   
            //Rebalance every 10 days:
            if (tradingDayCount >= rebalanceFrequency) 
            {   
                SetHoldings(symbol, 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]),
            };
        }
    }
}