Overall Statistics
using QuantConnect.Securities.Option;

namespace QuantConnect.Algorithm.CSharp
{
    /// <summary>
    /// Intraday price variation of a selected option contract.
    /// </summary>
    public class OptionsHistoryAlgorithm : QCAlgorithm
    {
        private const string UnderlyingTicker = "GLD";
        public readonly Symbol Underlying = QuantConnect.Symbol.Create(UnderlyingTicker, SecurityType.Equity, Market.USA);
        public readonly Symbol OptionSymbol = QuantConnect.Symbol.Create(UnderlyingTicker, SecurityType.Option, Market.USA);
        
        private OptionRight optType = OptionRight.Put;
        private readonly DateTime targetExpiry = DateTime.Parse("2011-12-17");
        private readonly decimal targetStrike = 165.0m;
        
        
        public override void Initialize()
        {
            SetStartDate(2011, 9, 21);
            SetEndDate(2011, 9, 21);
            SetCash(10000);

            var equity = AddEquity(UnderlyingTicker);
            var option = AddOption(UnderlyingTicker);

            equity.SetDataNormalizationMode(DataNormalizationMode.Raw);
            
            //option.PriceModel = OptionPriceModels.CrankNicolsonFD();
            //option.EnableGreekApproximation = true;

            //option.SetFilter(-10, +1, TimeSpan.FromDays(7), TimeSpan.FromDays(180));
            int expDaysAhead = (targetExpiry - Time).Days;
            option.SetFilter(universe => from symbol in universe
              .Expiration(TimeSpan.FromDays(expDaysAhead - 1), TimeSpan.FromDays(expDaysAhead + 1))
              where
                symbol.ID.OptionRight == optType &&
                Math.Abs(targetStrike - symbol.ID.StrikePrice) < 1.0m
              select symbol);
        }

        
        public override void OnData(Slice slice)
        {
            OptionChain chain;
            if (!Portfolio.Invested)
            {
                if (slice.OptionChains.TryGetValue(OptionSymbol, out chain))
                {
                    var contr = chain
                      .OrderBy(x => Math.Abs((x.Expiry - targetExpiry).Days))
                      .ThenBy(x => Math.Abs(targetStrike - x.Strike))
                      .FirstOrDefault();
                    
                    if (contr == null)
                    {
                    	Debug("No matching contract found");
            			return;
            		}
                    
                    Log(String.Format(@"{0},Bid={1} Ask={2} Last={3} OI={4}; Underlying={5}",
                             contr.Symbol.Value,
                             contr.BidPrice,
                             contr.AskPrice,
                             contr.LastPrice,
                             contr.OpenInterest,
                             contr.UnderlyingLastPrice
                       ));
                }
            }
        }
    }
}