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 |
using System; using System.Collections.Generic; using System.Linq; using QuantConnect.Data; using QuantConnect.Data.Market; namespace QuantConnect.Algorithm.CSharp.MyStuff.OptionsDataCheck { /// <summary> /// This is a crude (non-foolproof) algorithm to check for bulk missing options data files. /// /// For the specified options underlying, every day (at 2 hours after open) it checks to see if there is at least 1 ATM call /// and 1 ATM put for each of the expiry dates it's seen before. If none are found, it logs a debug message. /// /// It only checks monthly options with 65 or less days to expiration, but could be set to whatever in Initialize(). /// Also, there's a flag to invert the logging, to only log when there IS data available. /// </summary> public class ÒptionsDataCheckAlgo : QCAlgorithm { private Symbol _optionSymbol; private bool _checkNextSlice = false; List<DateTime> _existingExpiries = new List<DateTime>(); private bool _onlyLogWhenThereIsData = false; /// <summary> /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized. /// </summary> public override void Initialize() { //SetStartDate(2012, 1, 1); //SetEndDate(2018, 9, 1); SetStartDate(2018, 10, 1); SetEndDate( 2019, 2, 13); var option = AddOption("AAPL", Resolution.Minute); option.SetFilter(-1, 1, TimeSpan.FromDays(0), TimeSpan.FromDays(65)); _optionSymbol = option.Symbol; // Flag to invert the logging. _onlyLogWhenThereIsData = false; //true; // Flag to check next data slice every day 2 hours after market open. Schedule.On(DateRules.EveryDay(_optionSymbol), TimeRules.AfterMarketOpen(_optionSymbol, 120), () => _checkNextSlice = true); } /// <summary> /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. /// </summary> /// <param name="data">Slice object keyed by symbol containing the stock data</param> public override void OnData(Slice data) { if (!_checkNextSlice) return; _checkNextSlice = false; if (!IsMarketOpen(_optionSymbol)) { if (!_onlyLogWhenThereIsData) Debug("On " + Time.ToString("yyyy-MM-dd") + " market closed for " + _optionSymbol.ToString()); return; } OptionChain chain; if (data.OptionChains.TryGetValue(_optionSymbol, out chain)) { // Remove expired expiries. var expiredExpiries = _existingExpiries.Where(e => e.Date < Time.Date).ToList(); foreach (var expiry in expiredExpiries) { //Debug("Removing old expiry " + expiry.ToString("yyyy-MM-dd")); _existingExpiries.Remove(expiry); } // Add new expiries. var newExpiries = chain.Where(oc => !_existingExpiries.Contains(oc.Expiry)).Select(oc => oc.Expiry).Distinct(); foreach (var expiry in newExpiries) { //Debug("Adding new expiry " + expiry.ToString("yyyy-MM-dd")); _existingExpiries.Add(expiry); } // Check there is at least 1 expiry to check. if (!_onlyLogWhenThereIsData) { if (_existingExpiries.Count == 0) { Debug("On " + Time.ToString("yyyy-MM-dd") + " " + chain.Underlying.Symbol.ToString() + " there are no options expiries to check (i.e. missing all options)"); } } // Check if there's any calls & puts for each expiry. foreach (var expiry in _existingExpiries) { var calls = chain.Where(oc => oc.Expiry == expiry && oc.Right == OptionRight.Call).Count(); var puts = chain.Where(oc => oc.Expiry == expiry && oc.Right == OptionRight.Put).Count(); // Check for missing data. if (!_onlyLogWhenThereIsData) { if (calls == 0 || puts == 0) { Debug("On " + Time.ToString("yyyy-MM-dd") + " " + chain.Underlying.Symbol.ToString() + " options for expiry=" + expiry.ToString("yyyy-MM-dd") + " is missing: " + (calls == 0 ? "calls " : "") + (puts == 0 ? "puts " : "")); } } // Check for data. if (_onlyLogWhenThereIsData) { if (calls > 0 || puts > 0) { Debug("On " + Time.ToString("yyyy-MM-dd") + " " + chain.Underlying.Symbol.ToString() + " options for expiry=" + expiry.ToString("yyyy-MM-dd") + " exists for: " + (calls > 0 ? "calls " : "") + (puts > 0 ? "puts " : "")); } } } } else { if (!_onlyLogWhenThereIsData) Debug("On " + Time.ToString("yyyy-MM-dd") + " no options chain for " + _optionSymbol.ToString()); } } } }