Overall Statistics |
Total Orders 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Start Equity 100000 End Equity 100000 Net Profit 0% Sharpe Ratio 0 Sortino Ratio 0 Probabilistic 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 -2.089 Tracking Error 0.12 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset Portfolio Turnover 0% |
#region imports using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Globalization; using System.Drawing; using QuantConnect; using QuantConnect.Algorithm.Framework; using QuantConnect.Algorithm.Framework.Selection; using QuantConnect.Algorithm.Framework.Alphas; using QuantConnect.Algorithm.Framework.Portfolio; using QuantConnect.Algorithm.Framework.Execution; using QuantConnect.Algorithm.Framework.Risk; using QuantConnect.Algorithm.Selection; using QuantConnect.Parameters; using QuantConnect.Benchmarks; using QuantConnect.Brokerages; using QuantConnect.Util; using QuantConnect.Interfaces; using QuantConnect.Algorithm; using QuantConnect.Indicators; using QuantConnect.Data; using QuantConnect.Data.Consolidators; using QuantConnect.Data.Custom; using QuantConnect.DataSource; using QuantConnect.Data.Fundamental; using QuantConnect.Data.Market; using QuantConnect.Data.UniverseSelection; using QuantConnect.Notifications; using QuantConnect.Orders; using QuantConnect.Orders.Fees; using QuantConnect.Orders.Fills; using QuantConnect.Orders.Slippage; using QuantConnect.Scheduling; using QuantConnect.Securities; using QuantConnect.Securities.Equity; using QuantConnect.Securities.Future; using QuantConnect.Securities.Option; using QuantConnect.Securities.Forex; using QuantConnect.Securities.Crypto; using QuantConnect.Securities.Interfaces; using QuantConnect.Storage; using QCAlgorithmFramework = QuantConnect.Algorithm.QCAlgorithm; using QCAlgorithmFrameworkBridge = QuantConnect.Algorithm.QCAlgorithm; #endregion using MathNet.Numerics.Statistics; namespace QuantConnect.Algorithm.CSharp { public class FormalYellowGreenBison : QCAlgorithm { public override void Initialize() { UniverseSettings.Asynchronous = true; SetStartDate(2023, 1, 1); SetEndDate(2023, 7, 1); var underlyingSymbol = AddEquity("SPY", Resolution.Daily).Symbol; var option = AddOption(underlyingSymbol, Resolution.Daily); option.SetFilter(universe => { return universe.Contracts(contracts => { var contractsList = contracts.ToList(); var ivValues = contractsList.Select(symbol => { var mirror = QuantConnect.Symbol.CreateOption(symbol.Underlying, symbol.ID.Market, symbol.ID.OptionStyle, symbol.ID.OptionRight == OptionRight.Call ? OptionRight.Put : OptionRight.Call, symbol.ID.StrikePrice, symbol.ID.Date); var iv = new ImpliedVolatility(symbol, new InterestRateProvider(), new DividendYieldProvider(symbol.Underlying), mirror); // We know SPY equity and option exchange and data TZ are de same but in real cases we would need to get the config for both the option and the underlying var config = SubscriptionManager.Subscriptions.First(x => x.Symbol == option.Symbol); var end = Time.ConvertTo(TimeZone, option.Exchange.TimeZone).Date.AddDays(1); var start = QuantConnect.Time.GetStartTimeForTradeBars(option.Exchange.Hours, end, Resolution.Daily.ToTimeSpan(), 1, false, config.DataTimeZone); var endUtc = end.ConvertToUtc(option.Exchange.TimeZone); var startUtc = start.ConvertToUtc(option.Exchange.TimeZone); var underlyingHistoryRequest = new HistoryRequest( startUtc, endUtc, typeof(TradeBar), underlyingSymbol, Resolution.Daily, option.Exchange.Hours, config.DataTimeZone, Resolution.Daily, includeExtendedMarketHours: false, isCustomData: false, DataNormalizationMode.ScaledRaw, LeanData.GetCommonTickTypeForCommonDataTypes(typeof(TradeBar), SecurityType.Equity)); var optionHistoryRequest = new HistoryRequest( startUtc, endUtc, typeof(QuoteBar), option.Symbol, Resolution.Daily, option.Exchange.Hours, config.DataTimeZone, Resolution.Daily, includeExtendedMarketHours: false, isCustomData: false, DataNormalizationMode.ScaledRaw, LeanData.GetCommonTickTypeForCommonDataTypes(typeof(QuoteBar), SecurityType.Equity)); var mirrorHistoryRequest = new HistoryRequest( startUtc, endUtc, typeof(QuoteBar), mirror, Resolution.Daily, option.Exchange.Hours, config.DataTimeZone, Resolution.Daily, includeExtendedMarketHours: false, isCustomData: false, DataNormalizationMode.ScaledRaw, LeanData.GetCommonTickTypeForCommonDataTypes(typeof(QuoteBar), SecurityType.Equity)); var history = HistoryProvider.GetHistory(new [] { underlyingHistoryRequest, optionHistoryRequest, mirrorHistoryRequest }, TimeZone); foreach (var slice in history) { if (slice.Bars.TryGetValue(underlyingSymbol, out var underlyingTrade)) { var point = new IndicatorDataPoint(underlyingTrade.Symbol, underlyingTrade.EndTime, underlyingTrade.Close); iv.Update(point); } foreach (var quote in slice.QuoteBars.Values) { var point = new IndicatorDataPoint(quote.Symbol, quote.EndTime, quote.Close); iv.Update(point); } } return iv.Current.Value; }).ToList(); var ivMedian = ivValues.Median(); var minIv = ivMedian * 0.50m; var maxIv = ivMedian * 1.50m; var result = new List<Symbol>(); for (var i = 0; i < contractsList.Count; i++) { if (ivValues[i] >= minIv && ivValues[i] <= maxIv) { result.Add(contractsList[i]); } } return universe.Contracts(result.Take(0)); }); }); } } }