Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
0
Tracking Error
0
Treynor Ratio
0
Total Fees
$0.00
/*
* TODO dont reload data for first minutes if same contract?
 *
*/

using System;
using System.Collections.Generic;
using System.Linq;
using QuantConnect.Brokerages;
using QuantConnect.Data;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Orders;
using QuantConnect.Securities;

namespace QuantConnect.Algorithm.CSharp
{
   
    /// <summary>
   
    /// </summary>
    public class FuturesAlgo: QCAlgorithm
    {
        
        FuturesContract _contract = null;
        FuturesContract _nextContract = null;//holds the next contract, for warmup
        
        
        BollingerBands _bb = null;
        BollingerBands _nextBb = null;//holds the next FuturesContract

		bool _newDay = true;
		
        bool reset = true;
        public override void Initialize()
        {
            SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin);
            SetStartDate(year: 2017, month:6, day: 5);
            SetEndDate(year: 2017, month:6, day: 20);
            SetCash(100000);
            SetWarmUp(TimeSpan.FromDays(5));
            var future = AddFuture(Futures.Indices.SP500EMini, Resolution.Minute);
            future.SetFilter(TimeSpan.Zero, TimeSpan.FromDays(185));
        }

        
        public override void OnData(Slice slice)
        {
        	if (Time.Minute == 0)
        		Log("OnData");
        	if (!InitContract(slice))
            {
                return;
            }
            if(reset)
            {
            	//need to roll/close contract in position if any
            	reset = false;
            }
            if (Time.Minute == 0)
        	{
        		if (_bb != null && _bb.IsReady)
        		{
        			var price = 0m;
        			if (slice.Bars.ContainsKey(_contract.Symbol))
        				price = slice.Bars[_contract.Symbol].Close;
        			Log("OnData:" + Time.ToString() + " " + _contract.ToString()
        			+ " price: " + price
        			+ " BBL: " + _bb.LowerBand
        			+ " BBM: " + _bb.MiddleBand
        			+ " BBU: " + _bb.UpperBand);
			        if (slice.Bars.ContainsKey(_nextContract.Symbol))
        				price = slice.Bars[_nextContract.Symbol].Close;
        			Log("OnData:" + Time.ToString() + " " + _nextContract.ToString()
        			+ " NEXT price: " + price
        			+ " BBL: " + _nextBb.LowerBand
        			+ " BBM: " + _nextBb.MiddleBand
        			+ " BBU: " + _nextBb.UpperBand);
        		}
        		else
        		{
        			Log("BB not ready");
        		}
        	}
        	return;
        }

        private bool InitContract(Slice slice)
        {
        	if (!_newDay)//reset daily everyday we chekc whther futures need to be rolled
        	{
        		return true;
        	}
            
            if (_contract != null && (_contract.Expiry -Time.Date).TotalDays >=3) //rolling 3 days before expiry
            {
                return true;
            }
            
            //On Expiry we will reset contracts
            foreach (var chain in slice.FutureChains)
            {
            	Log(chain.ToString());
            	//when selecting contract if on expiry date, then skip first as it woudl be the same one!
            	int skip = 0;
            	if (_contract!= null)
            		Log("Expiry days away " + (_contract.Expiry -Time.Date).TotalDays + " - " + _contract.Expiry + " - " + Time.Date);
            	if (_contract!= null && (_contract.Expiry -Time.Date).TotalDays <=3)
            		skip = 1;
            	//only in the case of the first initialisation can we have skip=0 where we take the first future no matter what
            	//else we will skip the first future as it is the current one not yet expired!
            	
                var chainContracts = (
                    from futuresContract in chain.Value.OrderBy(x => x.Expiry)
                        //where futuresContract.Expiry > Time.Date.AddDays(90)
                    select futuresContract
                ).ToArray();
                if (chainContracts.Count() < skip+2)
                	return false;
                FuturesContract first = chainContracts[skip];
                FuturesContract second = chainContracts[skip+1];
                
                if (first != null && second != null)
                {
                	Log("RESET: " + first.Symbol + " - " + second.Symbol);
                	reset = true;
                	
                	if (first != null && (_contract == null || _contract.Symbol != first.Symbol))
                	{
                		if (_nextContract != null)
                		{
                			_bb = _nextBb;
                			_contract = _nextContract;
                		}
                		else
                		{
                			_contract = first;
		                    var oneHour = new TradeBarConsolidator(TimeSpan.FromMinutes(60));
		                    oneHour.DataConsolidated += OnHour;
							//register the consolidator for data.
							SubscriptionManager.AddConsolidator(_contract.Symbol, oneHour);
							_bb = BB(_contract.Symbol, 20, 2, MovingAverageType.Exponential, Resolution.Hour);	
							//the algo won't warmup this bit so we have to call up the history and feed it the hour points
							//however the History call seems to return 0 bars for hour resolution, so we call 50 * 60 miute for a 50 hours warmup
                            //var history = History(_contract.Symbol, 50*60, Resolution.Hour);
                            
                            var history = History(_contract.Symbol, 50*60, Resolution.Minute);
                            Log(history.Count().ToString());
                            foreach (var bar in history)
                            {
                                if (bar.EndTime.Minute == 0 // on the hour
                                && (Time - bar.EndTime).TotalMinutes >= 2) // probably unecessary but not this one as it would conflict
                                {
                                	Log(bar.ToString());
                                    _bb.Update(new IndicatorDataPoint(_contract.Symbol, bar.EndTime, bar.Close));
                                }
                            }
                            Log(_bb.IsReady.ToString());
                		}
                	}
                	
                	if (second != null && (_nextContract == null || _nextContract.Symbol != second.Symbol))
                	{
                		_nextContract = second;
	                    var oneHour = new TradeBarConsolidator(TimeSpan.FromMinutes(60));
	                    //bind event handler to data consolidated event.
	                    oneHour.DataConsolidated += OnHour;
			
						//register the consolidator for data.
						SubscriptionManager.AddConsolidator(_nextContract.Symbol, oneHour);
						_nextBb = BB(_nextContract.Symbol, 20, 2, MovingAverageType.Exponential, Resolution.Hour);	
                	}
                    _newDay = false;
                    return true;
                }
            }
            return false;
        }

		public void OnHour(object sender, TradeBar bar)
		{
			//Log("do something and make sure indicators are udpated");
		}	
		
		public override void OnEndOfDay()
        {
            _newDay = true;
        }
    }
}