/// <summary> /// For Black-Scholes-Merton model price calculation relies <see cref="IOptionPriceModel"/> of the security /// </summary> /// <param name="maximumPercentDeviation">The maximum percent deviation. This value is in percent space, /// so a value of 1m is equal to 1%.</param> /// <param name="referenceDate">current reference date</param> /// <returns>A new decimal suitable for usage as new security price</returns> public decimal NextValue(decimal maximumPercentDeviation, DateTime referenceDate) { return(_option.PriceModel .Evaluate( _option, null, OptionContract.Create( _option.Symbol, _option.Symbol.Underlying, referenceDate, _option, _option.Underlying.Price )) .TheoreticalPrice); }
private bool HandleOptionData(DateTime algorithmTime, BaseData baseData, OptionChains optionChains, ISecurityPrice security, Lazy <Slice> sliceFuture, IReadOnlyDictionary <Symbol, BaseData> optionUnderlyingUpdates) { var symbol = baseData.Symbol; OptionChain chain; var canonical = symbol.Canonical; if (!optionChains.TryGetValue(canonical, out chain)) { chain = new OptionChain(canonical, algorithmTime); optionChains[canonical] = chain; } // set the underlying current data point in the option chain var option = security as IOptionPrice; if (option != null) { if (option.Underlying == null) { Log.Error($"TimeSlice.HandleOptionData(): {algorithmTime}: Option underlying is null"); return(false); } BaseData underlyingData; if (!optionUnderlyingUpdates.TryGetValue(option.Underlying.Symbol, out underlyingData)) { underlyingData = option.Underlying.GetLastData(); } if (underlyingData == null) { Log.Error($"TimeSlice.HandleOptionData(): {algorithmTime}: Option underlying GetLastData returned null"); return(false); } chain.Underlying = underlyingData; } var universeData = baseData as BaseDataCollection; if (universeData != null) { if (universeData.Underlying != null) { foreach (var addedContract in chain.Contracts) { addedContract.Value.UnderlyingLastPrice = chain.Underlying.Price; } } foreach (var contractSymbol in universeData.FilteredContracts) { chain.FilteredContracts.Add(contractSymbol); } return(false); } OptionContract contract; if (!chain.Contracts.TryGetValue(baseData.Symbol, out contract)) { contract = OptionContract.Create(baseData, security, chain.Underlying.Price); chain.Contracts[baseData.Symbol] = contract; if (option != null) { contract.SetOptionPriceModel(() => option.EvaluatePriceModel(sliceFuture.Value, contract)); } } // populate ticks and tradebars dictionaries with no aux data switch (baseData.DataType) { case MarketDataType.Tick: var tick = (Tick)baseData; chain.Ticks.Add(tick.Symbol, tick); UpdateContract(contract, tick); break; case MarketDataType.TradeBar: var tradeBar = (TradeBar)baseData; chain.TradeBars[symbol] = tradeBar; UpdateContract(contract, tradeBar); break; case MarketDataType.QuoteBar: var quote = (QuoteBar)baseData; chain.QuoteBars[symbol] = quote; UpdateContract(contract, quote); break; case MarketDataType.Base: chain.AddAuxData(baseData); break; } return(true); }