public PortfolioGreeks(long optionAvailableQuantity, Greeks optionGreeks, string optionSide, long premiumMultiplier) { _optionAvailableQuantity = optionAvailableQuantity; _optionGreeks = optionGreeks; _optionSide = optionSide; _premiumMultiplier = premiumMultiplier; }
public override int GetHashCode() { unchecked { int hashCode = (SecurityCode != null ? SecurityCode.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (OptionNumber != null ? OptionNumber.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (OptionCode != null ? OptionCode.GetHashCode() : 0); hashCode = (hashCode * 397) ^ Bid.GetHashCode(); hashCode = (hashCode * 397) ^ BidVolume.GetHashCode(); hashCode = (hashCode * 397) ^ Ask.GetHashCode(); hashCode = (hashCode * 397) ^ AskVolume.GetHashCode(); hashCode = (hashCode * 397) ^ Volume.GetHashCode(); hashCode = (hashCode * 397) ^ Bid2.GetHashCode(); hashCode = (hashCode * 397) ^ BidVolume2.GetHashCode(); hashCode = (hashCode * 397) ^ Ask2.GetHashCode(); hashCode = (hashCode * 397) ^ AskVolume2.GetHashCode(); hashCode = (hashCode * 397) ^ Bid3.GetHashCode(); hashCode = (hashCode * 397) ^ BidVolume3.GetHashCode(); hashCode = (hashCode * 397) ^ Ask3.GetHashCode(); hashCode = (hashCode * 397) ^ AskVolume3.GetHashCode(); hashCode = (hashCode * 397) ^ Bid4.GetHashCode(); hashCode = (hashCode * 397) ^ BidVolume4.GetHashCode(); hashCode = (hashCode * 397) ^ Ask4.GetHashCode(); hashCode = (hashCode * 397) ^ AskVolume4.GetHashCode(); hashCode = (hashCode * 397) ^ Bid5.GetHashCode(); hashCode = (hashCode * 397) ^ BidVolume5.GetHashCode(); hashCode = (hashCode * 397) ^ Ask5.GetHashCode(); hashCode = (hashCode * 397) ^ AskVolume5.GetHashCode(); hashCode = (hashCode * 397) ^ (Greeks != null ? Greeks.GetHashCode() : 0); hashCode = (hashCode * 397) ^ OpenInterest.GetHashCode(); hashCode = (hashCode * 397) ^ Turnover.GetHashCode(); hashCode = (hashCode * 397) ^ UncoveredPositionQuantity.GetHashCode(); hashCode = (hashCode * 397) ^ PreviousSettlementPrice.GetHashCode(); hashCode = (hashCode * 397) ^ OpeningPrice.GetHashCode(); hashCode = (hashCode * 397) ^ AuctionReferencePrice.GetHashCode(); hashCode = (hashCode * 397) ^ AuctionReferenceQuantity.GetHashCode(); hashCode = (hashCode * 397) ^ HighestPrice.GetHashCode(); hashCode = (hashCode * 397) ^ LowestPrice.GetHashCode(); hashCode = (hashCode * 397) ^ LatestTradedPrice.GetHashCode(); hashCode = (hashCode * 397) ^ Change.GetHashCode(); hashCode = (hashCode * 397) ^ ChangePercentage.GetHashCode(); hashCode = (hashCode * 397) ^ PreviousClose.GetHashCode(); hashCode = (hashCode * 397) ^ (Name != null ? Name.GetHashCode() : 0); return(hashCode); } }
public void CheckGreeks(OptionChain contracts) { if (!_checkGreeks || !contracts.Any()) { return; } _checkGreeks = false; _triedGreeksCalculation = true; foreach (var contract in contracts) { Greeks greeks = new Greeks(); try { greeks = contract.Greeks; // Greeks should have not been successfully accessed if the option style is not supported if (!_optionStyleIsSupported) { throw new Exception($"Expected greeks not to be calculated for {contract.Symbol.Value}, an {_option.Style} style option, using {_option?.PriceModel.GetType().Name}, which does not support them, but they were"); } } catch (ArgumentException) { // ArgumentException is only expected if the option style is not supported if (_optionStyleIsSupported) { throw new Exception($"Expected greeks to be calculated for {contract.Symbol.Value}, an {_option.Style} style option, using {_option?.PriceModel.GetType().Name}, which supports them, but they were not"); } } // Greeks shpould be valid if they were successfuly accessed for supported option style if (_optionStyleIsSupported) { if (greeks.Delta == 0m && greeks.Gamma == 0m && greeks.Theta == 0m && greeks.Vega == 0m && greeks.Rho == 0m) { throw new Exception($"Expected greeks to not be zero simultaneously for {contract.Symbol.Value}, an {_option.Style} style option, using {_option?.PriceModel.GetType().Name}, but they were"); } if (((contract.Right == OptionRight.Call && (greeks.Delta < 0m || greeks.Delta > 1m || greeks.Rho < 0m)) || (contract.Right == OptionRight.Put && (greeks.Delta < -1m || greeks.Delta > 0m || greeks.Rho > 0m)) || greeks.Vega < 0m || greeks.Gamma < 0m)) { throw new Exception($"Expected greeks to have valid values. Greeks were: Delta: {greeks.Delta}, Rho: {greeks.Rho}, Theta: {greeks.Theta}, Vega: {greeks.Vega}, Gamma: {greeks.Gamma}"); } } } }
public Greeks GetStrategyGreeks(double at_price, DateTime at_date) { Greeks value = new Greeks(); value.delta = 0; value.gamma = 0; value.theta = 0; value.vega = 0; for (int i = 0; i < core.PositionsTable.Rows.Count; i++) { value += GetPositionGreeks(i, at_price, at_date, double.NaN); } return(value); }
public Greeks Greeks(Quote quote, Option option, double interest, double dividend_rate, double volatility, double option_price) { Greeks greeks = new Greeks(); TimeSpan ts = option.expiration - DateTime.Now; greeks.time = ts.TotalDays / 365.0; greeks.interest = interest * 0.01; greeks.dividend_rate = dividend_rate; if (double.IsNaN(option_price)) { if (double.IsNaN(option.price.ask) || double.IsNaN(option.price.bid)) { option_price = option.price.last; } else { option_price = (option.price.ask + option.price.bid) * 0.5; } } if (double.IsNaN(volatility)) { volatility = ImpliedVolatility(option.type, option_price, quote.price.last, option.strike, greeks.interest, greeks.dividend_rate, greeks.time); } else { volatility = volatility * 0.01; } if (!double.IsNaN(volatility)) { greeks.implied_volatility = volatility * 100; greeks.delta = Delta(option.type, quote.price.last, option.strike, greeks.interest, greeks.dividend_rate, volatility, greeks.time); greeks.gamma = Gamma(quote.price.last, option.strike, greeks.interest, greeks.dividend_rate, volatility, greeks.time); greeks.vega = Vega(quote.price.last, option.strike, greeks.interest, greeks.dividend_rate, volatility, greeks.time) / 100.0; greeks.theta = Theta(option.type, quote.price.last, option.strike, greeks.interest, greeks.dividend_rate, volatility, greeks.time) / 365.0; } return(greeks); }
public static Greeks GetGreeks(double daysToExpiry /*T-t, maturity*/, double strike /*K*/, double interestRate /*r*/, double spotPrice /*S*/, double ask, double bid, double lastPrice, LegType callOrPut, double?divYield = null) { if (divYield == null) { divYield = 0; } BlackScholesModel bsm = new BlackScholesModel(daysToExpiry, strike, interestRate, spotPrice, ask, bid, lastPrice, callOrPut, divYield); Greeks greeks = new Greeks(); greeks.Delta = bsm.EuroDelta; greeks.Gamma = bsm.EuroGamma; greeks.Theta = bsm.EuroTheta; greeks.Sigma = bsm.Sigma; greeks.Rho = bsm.EuroRho; greeks.RhoFx = bsm.EuroRhoFx; greeks.Vega = bsm.EuroVega; return(greeks); }
internal static void GetOptGreek(IEnumerable <IPosition> positions, double f, double k, double dT, double sigma, double ratePct, bool isCall, Greeks greek, out double optGreek) { optGreek = 0; foreach (IPosition pos in positions) { // Пока что State лучше не трогать //if (pos.PositionState == PositionState.HaveError) { int sign = pos.IsLong ? 1 : -1; double qty = Math.Abs(pos.Shares); double tmp; switch (greek) { case Greeks.Delta: tmp = FinMath.GetOptionDelta(f, k, dT, sigma, ratePct, isCall); break; case Greeks.Theta: tmp = FinMath.GetOptionTheta(f, k, dT, sigma, ratePct, isCall); break; case Greeks.Vega: tmp = FinMath.GetOptionVega(f, k, dT, sigma, ratePct, isCall); break; case Greeks.Gamma: tmp = FinMath.GetOptionGamma(f, k, dT, sigma, ratePct, isCall); break; default: throw new NotImplementedException("Greek '" + greek + "' is not yet supported."); } optGreek += sign * tmp * qty; } } }
public void ModelDifferencesCompare() { var greeksYesterday = new Greeks { Delta = 10D, Gamma = 0.25D, }; var greeksToday = new Greeks { Delta = 15D, Gamma = 0.40D }; var pricesYesterday = new Prices { Close = 1.5D }; var pricesToday = new Prices { Close = 2.0D }; var diffs = new ModelDifferences(); diffs.Compare(greeksYesterday, greeksToday, pricesYesterday, pricesToday); Assert.AreEqual(greeksYesterday.Delta - greeksToday.Delta, diffs.Delta.Difference); var difGamma = (greeksYesterday.Gamma * 100) - (greeksToday.Gamma * 100D); Assert.AreEqual(difGamma, diffs.Gamma.Difference); Assert.AreEqual(pricesYesterday.Close - pricesToday.Close, diffs.Close.Difference); }
public List <BasePortfolioItemGroupViewModel> GetPortfolioData(string customerCode, string accountCode, string tradeAccount) { #region Fetch data OptionPositionsArguments arguments = new OptionPositionsArguments { CustomerCode = customerCode, CustomerAccountCode = accountCode }; EntityResponse <List <OptionPositionInformation> > optionPositions = _portfolioManager.GetOptionPositions(arguments); EntityResponse <List <OptionableStockPositionInformation> > stockPositions = _portfolioManager.GetOptionalStockPositions(customerCode, accountCode, tradeAccount); if (!optionPositions.IsSuccess || !stockPositions.IsSuccess || optionPositions.Entity.Count == 0) { return(new List <BasePortfolioItemGroupViewModel>()); } IEnumerable <PortfolioOption> portfolioOptions = Mapper.Map <List <OptionPositionInformation>, List <PortfolioOption> >(optionPositions.Entity); IEnumerable <PortfolioStock> portfolioStocks = Mapper.Map <List <OptionableStockPositionInformation>, List <PortfolioStock> >(stockPositions.Entity); Dictionary <string, EntityResponse <OptionChain> > optionChains = new Dictionary <string, EntityResponse <OptionChain> >(); #endregion #region Fill additional information foreach (PortfolioOption portfolioItem in portfolioOptions) { EntityResponse <List <OptionBasicInformation> > optionBasicInformation = _marketDataProviderQueryable.GetOptionBasicInformation(optionNumber: portfolioItem.OptionNumber); if (optionBasicInformation.Entity == null || !optionBasicInformation.Entity.Any()) { continue; } OptionBasicInformation basicInfo = optionBasicInformation.Entity.Single(); DateTime expiryDate = basicInfo.ExpireDate; DateAndNumberOfDaysUntil expiry = _marketWorkTimeService.GetNumberOfDaysLeftUntilExpiry(expiryDate); portfolioItem.Expiry = expiry; portfolioItem.UnderlyingCode = basicInfo.OptionUnderlyingCode; portfolioItem.UnderlyingName = basicInfo.OptionUnderlyingName; portfolioItem.StrikePrice = basicInfo.StrikePrice; EntityResponse <OptionChain> optionChain; string underlying = portfolioItem.UnderlyingCode; if (optionChains.ContainsKey(underlying)) { optionChain = optionChains[underlying]; } else { optionChain = _marketDataService.GetOptionChain(underlying); optionChains.Add(underlying, optionChain); } if (optionChain == null) { continue; } Option option = optionChain.Entity[portfolioItem.OptionNumber]; if (option == null) { portfolioItem.UnderlyingCode = null; continue; } Greeks greeks = option.Greeks ?? new Greeks(); portfolioItem.LastPrice = (decimal)option.LatestTradedPrice; //optionChain.Entity.UnderlyingCurrentPrice; portfolioItem.PremiumMultiplier = option.RootPair.PremiumMultiplier; portfolioItem.Greeks = new PortfolioGreeks(portfolioItem.OptionAvailableQuantity, greeks, portfolioItem.OptionSide, portfolioItem.PremiumMultiplier); } portfolioOptions = portfolioOptions.Where(x => x.UnderlyingCode != null); foreach (PortfolioStock portfolioStock in portfolioStocks) { SecurityQuotation quote = _marketDataService.GetSecurityQuotation(portfolioStock.SecurityCode); portfolioStock.LastPrice = quote.LastPrice; portfolioStock.StockMarketValue = quote.LastPrice * portfolioStock.AvailableBalance; portfolioStock.Greeks = new PortfolioGreeks(portfolioStock.AdjustedAvailableQuantity, new Greeks() { Delta = 1 }, portfolioStock.OptionSide, 1); } #endregion IEnumerable <BasePortfolioItemGroup> groupedByStrategies = _strategyService.GetPortfolioItemsGroupedByStrategy(portfolioOptions, portfolioStocks); List <BasePortfolioItemGroupViewModel> result = Mapper.Map <IEnumerable <BasePortfolioItemGroup>, IEnumerable <BasePortfolioItemGroupViewModel> >(groupedByStrategies) .ToList(); return(result); }
public Greeks GetPositionGreeks(int index, double at_price, DateTime at_date, double at_volatility) { Greeks value = new Greeks(); value.delta = 0; value.gamma = 0; value.theta = 0; value.vega = 0; // get entry row DataRow row = null; try { row = core.PositionsTable.Rows[index]; } catch { } if (row == null || row["Type"] == DBNull.Value) { return(value); } try { bool enabled = (bool)row["Enable"]; string symbol = (string)row["Symbol"]; if (enabled && symbol != "") { // quantity of stocks/contracts int quantity = 0; if (row["Quantity"] != DBNull.Value) { quantity = (int)row["Quantity"]; } // strike price double strike = double.NaN; if (row["Strike"] != DBNull.Value) { strike = (double)row["Strike"]; } // volatility double volatility = at_volatility; if (double.IsNaN(volatility) && row["Volatility"] != DBNull.Value) { volatility = (double)row["Volatility"] * 0.01; } // time to expiration double time = 0; if (row["Expiration"] != DBNull.Value) { time = (double)((TimeSpan)((DateTime)row["Expiration"] - at_date)).TotalDays / 365.0; } // federal interest double dividend_rate = core.StockDividendRate; // federal interest double interest = Config.Local.FederalIterest * 0.01; switch ((string)row["Type"]) { case "Long Stock": value.delta = quantity; value.gamma = 0; value.theta = 0; value.vega = 0; break; case "Short Stock": value.delta = -quantity; value.gamma = 0; value.theta = 0; value.vega = 0; break; case "Long Call": value.delta = quantity * core.GetStocksPerContract(symbol) * Algo.Model.Delta("Call", at_price, strike, interest, dividend_rate, volatility, time); value.gamma = quantity * core.GetStocksPerContract(symbol) * Algo.Model.Gamma(at_price, strike, interest, dividend_rate, volatility, time); value.theta = quantity * core.GetStocksPerContract(symbol) * Algo.Model.Theta("Call", at_price, strike, interest, dividend_rate, volatility, time); value.vega = quantity * core.GetStocksPerContract(symbol) * Algo.Model.Vega(at_price, strike, interest, dividend_rate, volatility, time); break; case "Short Call": value.delta = -quantity *core.GetStocksPerContract(symbol) * Algo.Model.Delta("Call", at_price, strike, interest, dividend_rate, volatility, time); value.gamma = -quantity *core.GetStocksPerContract(symbol) * Algo.Model.Gamma(at_price, strike, interest, dividend_rate, volatility, time); value.theta = -quantity *core.GetStocksPerContract(symbol) * Algo.Model.Theta("Call", at_price, strike, interest, dividend_rate, volatility, time); value.vega = -quantity *core.GetStocksPerContract(symbol) * Algo.Model.Vega(at_price, strike, interest, dividend_rate, volatility, time); break; case "Long Put": value.delta = quantity * core.GetStocksPerContract(symbol) * Algo.Model.Delta("Put", at_price, strike, interest, dividend_rate, volatility, time); value.gamma = quantity * core.GetStocksPerContract(symbol) * Algo.Model.Gamma(at_price, strike, interest, dividend_rate, volatility, time); value.theta = quantity * core.GetStocksPerContract(symbol) * Algo.Model.Theta("Put", at_price, strike, interest, dividend_rate, volatility, time); value.vega = quantity * core.GetStocksPerContract(symbol) * Algo.Model.Vega(at_price, strike, interest, dividend_rate, volatility, time); break; case "Short Put": value.delta = -quantity *core.GetStocksPerContract(symbol) * Algo.Model.Delta("Put", at_price, strike, interest, dividend_rate, volatility, time); value.gamma = -quantity *core.GetStocksPerContract(symbol) * Algo.Model.Gamma(at_price, strike, interest, dividend_rate, volatility, time); value.theta = -quantity *core.GetStocksPerContract(symbol) * Algo.Model.Theta("Put", at_price, strike, interest, dividend_rate, volatility, time); value.vega = -quantity *core.GetStocksPerContract(symbol) * Algo.Model.Vega(at_price, strike, interest, dividend_rate, volatility, time); break; } } } catch { } return(value); }
public void CalculateAllPositionImpliedVolatility() { if (core.PositionsTable == null) { return; } core.PositionsTable.BeginLoadData(); for (int i = 0; i < core.PositionsTable.Rows.Count; i++) { DataRow row = core.PositionsTable.Rows[i]; if (row["Type"] != DBNull.Value) { row.BeginEdit(); try { // short or long position? bool short_pos = row["Type"].ToString().Contains("Short"); // quantity and sign factor double q = (int)row["Quantity"] * core.GetStocksPerContract((string)row["Symbol"]); if (short_pos) { q = -q; } if (row["Type"].ToString().Contains("Stock")) { row["ImpliedVolatility"] = 0; row["Delta"] = q; row["Gamma"] = 0; row["Vega"] = 0; row["Theta"] = 0; continue; } // calculate implied volatility based on the close price of this position. if the position is short we need the long price (open price). // if the position is long we need the short price (close price). double option_price = core.GetSymbolPrice((string)row["Symbol"], short_pos, Config.Local.LastPriceModel); // calculate implied volatility & other greeks based on option-price Greeks greeks = core.GetGreeksBySymbol((string)row["Symbol"], option_price); double timev = core.GetOptionField((string)row["Symbol"], "TimeValue"); if (!double.IsNaN(greeks.implied_volatility)) { row["ImpliedVolatility"] = greeks.implied_volatility; } else { row["ImpliedVolatility"] = DBNull.Value; if (((int)row["Flags"] & OptionsSet.PositionsTableDataTable.FLAG_MANUAL_VOLATILITY) == 0) { row["Volatility"] = DBNull.Value; } } if (!double.IsNaN(greeks.delta)) { row["Delta"] = q * greeks.delta; } else { row["Delta"] = DBNull.Value; } if (!double.IsNaN(greeks.gamma)) { row["Gamma"] = q * greeks.gamma; } else { row["Gamma"] = DBNull.Value; } if (!double.IsNaN(greeks.vega)) { row["Vega"] = q * greeks.vega; } else { row["Vega"] = DBNull.Value; } if (!double.IsNaN(greeks.theta)) { row["Theta"] = q * greeks.theta; } else { row["Theta"] = DBNull.Value; } if (!double.IsNaN(greeks.theta)) { row["TimeValue"] = timev; } else { row["TimeValue"] = DBNull.Value; } if (((int)row["Flags"] & OptionsSet.PositionsTableDataTable.FLAG_MANUAL_VOLATILITY) == 0) { double volatility = double.NaN; int flags = (int)row["Flags"] & (~OptionsSet.PositionsTableDataTable.FLAG_VOLATILITY_FALLBACK); try { switch (Config.Local.GetParameter("Volatility Mode")) { case "Stock HV": volatility = core.GetStockVolatility("Historical"); break; case "Stock IV": volatility = core.GetStockVolatility("Implied"); break; case "Option IV": if (!double.IsNaN(greeks.implied_volatility)) { volatility = greeks.implied_volatility; } else { if (Config.Local.GetParameter("Implied Volatility Fallback") == "Yes") { volatility = core.GetStockVolatility("Implied"); } flags |= OptionsSet.PositionsTableDataTable.FLAG_VOLATILITY_FALLBACK; } break; case "Fixed V": volatility = double.Parse(Config.Local.GetParameter("Fixed Volatility")); break; } } catch { } if (!double.IsNaN(volatility)) { row["Volatility"] = volatility; } else { flags |= OptionsSet.PositionsTableDataTable.FLAG_VOLATILITY_FALLBACK; row["Volatility"] = double.NaN; } // update flags row["Flags"] = flags; } } catch { } row.EndEdit(); } } core.PositionsTable.EndLoadData(); }
internal static void GetPairGreek(PositionsManager posMan, InteractiveSeries smile, IOptionStrikePair pair, double f, double dT, Greeks greek, out double totalGreek) { totalGreek = 0; ISecurity putSec = pair.Put.Security, callSec = pair.Call.Security; // закрытые позы не дают в клада в дельту, поэтому беру только активные ReadOnlyCollection <IPosition> putPositions = posMan.GetActiveForBar(putSec); ReadOnlyCollection <IPosition> callPositions = posMan.GetActiveForBar(callSec); if ((putPositions.Count <= 0) && (callPositions.Count <= 0)) { return; } double?sigma = null; if ((smile.Tag != null) && (smile.Tag is SmileInfo)) { double tmp; SmileInfo info = smile.GetTag <SmileInfo>(); if (info.ContinuousFunction.TryGetValue(pair.Strike, out tmp)) { sigma = tmp; } } if (sigma == null) { sigma = (from d2 in smile.ControlPoints let point = d2.Anchor.Value where (DoubleUtil.AreClose(pair.Strike, point.X)) select(double?) point.Y).FirstOrDefault(); } if (sigma == null) { return; } { double putGreek; GetOptGreek(putPositions, f, pair.Strike, dT, sigma.Value, 0.0, false, greek, out putGreek); totalGreek += putGreek; } { double callGreek; GetOptGreek(callPositions, f, pair.Strike, dT, sigma.Value, 0.0, true, greek, out callGreek); totalGreek += callGreek; } }
internal static void GetBaseGreek(PositionsManager posMan, ISecurity sec, int barNum, double f, Greeks greek, out double rawGreek) { rawGreek = 0; switch (greek) { case Greeks.Delta: BlackScholesDelta.GetBaseDelta(posMan, sec, barNum, f, out rawGreek); break; default: // на первый взгляд все греки БА кроме дельты равны 0 return; } }
/// <summary> /// Initializes a new instance of the <see cref="OptionPriceModelResult"/> class /// </summary> /// <param name="theoreticalPrice">The theoretical price computed by the price model</param> /// <param name="greeks">The sensitivities (greeks) computed by the price model</param> public OptionPriceModelResult(decimal theoreticalPrice, Greeks greeks) { TheoreticalPrice = theoreticalPrice; _impliedVolatility = new Lazy <decimal>(() => 0m); _greeks = new Lazy <Greeks>(() => greeks); }
private void UpdateCell(int index, double underlying, DateTime end_date, double volatility) { bool new_row = false; DataRow row = data.AnalysisTable.FindByIndex(index); if (row == null) { row = data.AnalysisTable.NewRow(); new_row = true; } // calculate strategy return double ret; Greeks grk; if (!double.IsNaN(underlying) && end_date != DateTime.MinValue) { ret = (double)core.om.GetStrategyReturn(underlying, end_date, volatility); grk = core.om.GetStrategyGreeks(underlying, end_date, volatility); } else { ret = double.NaN; grk = new Greeks(); } // calculate strategy greeks // update analysis points row["Price"] = underlying; if (double.IsNaN(volatility)) { row["Volatility"] = DBNull.Value; } else { row["Volatility"] = volatility; } row["EndDate"] = end_date; // update analyis result row["Profit"] = ret; row["ProfitPrc"] = ret / net_investment; // update greeks if (double.IsNaN(grk.delta)) { row["Delta"] = DBNull.Value; } else { row["Delta"] = grk.delta; } if (double.IsNaN(grk.gamma)) { row["Gamma"] = DBNull.Value; } else { row["Gamma"] = grk.gamma; } if (double.IsNaN(grk.theta)) { row["Theta"] = DBNull.Value; } else { row["Theta"] = grk.theta / 365.0; } if (double.IsNaN(grk.vega)) { row["Vega"] = DBNull.Value; } else { row["Vega"] = grk.vega / 100.0; } // add row to list of rows if this is a new row if (new_row) { data.AnalysisTable.Rows.Add(row); } }