public static void Compute(OptionPosition option) { IOptionsPricingModel pricingModel; switch (option.Model) { case OptionPricingModel.Binomial: pricingModel = new BinomialModel(); break; case OptionPricingModel.BlackScholes: pricingModel = new BlackScholesModel(); break; case OptionPricingModel.ExpliciteFiniteDifference: pricingModel = new ExpliciteFiniteDifferenceModel(); break; case OptionPricingModel.Trinomial: pricingModel = new TrinomialModel(); break; default: throw new InvalidOperationException($"No implementation for {option.Model}"); } pricingModel.Compute(option); }
public void TestVolSurface() { IVolatilitySurface volSurface = new VolatilitySurface("BHP", 4500M, DateTime.Today); ForwardExpiry expiry1 = new ForwardExpiry(DateTime.Parse("01-Jan-2010"), 4200); ForwardExpiry expiry2 = new ForwardExpiry(DateTime.Parse("01-Jan-2011"), 4400); OptionPosition call1 = new OptionPosition("1245", 104, PositionType.Call); OptionPosition put1 = new OptionPosition("1246", 1200, PositionType.Put); OptionPosition call2 = new OptionPosition("1645", 180, PositionType.Call); OptionPosition put2 = new OptionPosition("1646", 1300, PositionType.Put); Strike strike1 = new Strike(4200, call1, put1); Strike strike2 = new Strike(4000, call2, put2); IVolatilityPoint point1 = new VolatilityPoint(); point1.SetVolatility(0.30M, VolatilityState.Default()); put1.SetVolatility(point1); call1.SetVolatility(point1); IVolatilityPoint point2 = new VolatilityPoint(); point2.SetVolatility(0.40M, VolatilityState.Default()); call2.SetVolatility(point2); put2.SetVolatility(point2); expiry1.AddStrike(strike1, true); expiry2.AddStrike(strike2, false); volSurface.AddExpiry(expiry1); volSurface.AddExpiry(expiry2); List <ForwardExpiry> forwardExpiries = volSurface.NodalExpiries.ToList(); int n1 = forwardExpiries[0].Strikes.Count(item => item.NodalPoint); // int n2 = forwardExpiries[1].Strikes.Count(delegate(Strike item) { return item.NodalPoint == true; }); int n2 = 0; Assert.AreEqual(1, n1 + n2); }
public void None_CreatesOptionPosition_WithZeroQuantity() { var none = OptionPosition.None(Symbols.SPY); Assert.AreEqual(0, none.Quantity); Assert.AreEqual(Symbols.SPY, none.Symbol); }
public void Compute(OptionPosition option) { var t = option.TimeToExpiry.Days / 365.0; var d1 = (Math.Log(option.UnderlyingPrice / option.Strike) + (option.InterestRate - option.DividendRate + option.Volatility * option.Volatility / 2) * t) / (option.Volatility * Math.Sqrt(t)); var d2 = d1 - option.Volatility * Math.Sqrt(t); var sign = option.Side == Side.Buy ? 1 : -1; // when calculating option greeks keep in mind that we calculate greek for position, // and that's why BS formulas for greeks must be multiplied by -1 in case we're selling options // so formulas for greeks are [sign * BSFormula] if (option.Type == OptionType.Call) { option.OptionPrice = option.UnderlyingPrice * Math.Pow(Math.E, -option.DividendRate * t) * NormalDistribution.Phi(d1) - option.Strike * Math.Pow(Math.E, -option.InterestRate * t) * NormalDistribution.Phi(d2); option.Delta = sign * Math.Pow(Math.E, -option.DividendRate * t) * NormalDistribution.Phi(d1); option.Theta = sign * (-(option.UnderlyingPrice * Math.Pow(Math.E, -option.DividendRate * t) * NormalDistribution.Density(d1) * option.Volatility) / (2 * Math.Sqrt(t)) - option.InterestRate * option.Strike * Math.Pow(Math.E, -option.InterestRate * t) * NormalDistribution.Phi(d2)); option.Rho = sign * option.Strike * t * Math.Pow(Math.E, -option.InterestRate * t) * NormalDistribution.Phi(d2); } else { option.OptionPrice = -option.UnderlyingPrice * Math.Pow(Math.E, -option.DividendRate * t) * NormalDistribution.Phi(-d1) + option.Strike * Math.Pow(Math.E, -option.InterestRate * t) * NormalDistribution.Phi(-d2); option.Delta = sign * Math.Pow(Math.E, -option.DividendRate * t) * (NormalDistribution.Phi(d1) - 1); option.Theta = sign * (-(option.UnderlyingPrice * Math.Pow(Math.E, -option.DividendRate * t) * NormalDistribution.Density(d1) * option.Volatility) / (2 * Math.Sqrt(t)) + option.InterestRate * option.Strike * Math.Pow(Math.E, -option.InterestRate * t) * NormalDistribution.Phi(-d2)); option.Rho = sign * (-1) * option.Strike * t * Math.Pow(Math.E, -option.InterestRate * t) * NormalDistribution.Phi(-d2); } option.Gamma = sign * Math.Pow(Math.E, -option.DividendRate * t) * NormalDistribution.Density(d1) / (option.UnderlyingPrice * option.Volatility * Math.Sqrt(t)); option.Vega = sign * option.UnderlyingPrice * Math.Sqrt(t) * Math.Pow(Math.E, -option.DividendRate * t) * NormalDistribution.Density(d1); }
public void Compute(OptionPosition option) { var t = option.TimeToExpiry.TotalDays / 365.0; if (Math.Abs(t) < Double.Epsilon) { return; } var d1 = Math.Log(option.UnderlyingPrice / option.Strike) + (option.InterestRate - option.DividendRate + Math.Pow(option.Volatility, 2)) / t; var d2 = d1 - option.Volatility * Math.Sqrt(t); // when calculating option greeks keep in mind that we calculate greek for position, // and that's why BS formulas for greeks must be multiplied by -1 in case we're selling options // so formulas for greeks are [sign * BSFormula] if (option.Type == OptionType.Call) { option.OptionPrice = option.UnderlyingPrice * NormalDistribution.Phi(d1) - option.Strike * Math.Exp(-option.InterestRate * t) * NormalDistribution.Phi(d2); option.Delta = Math.Exp(-option.DividendRate * t) * NormalDistribution.Phi(d1); option.Theta = -Math.Exp(-option.DividendRate * t) * option.UnderlyingPrice * NormalDistribution.Density(d1) * option.Volatility / (2 * Math.Sqrt(t)) + option.DividendRate * Math.Exp(-option.DividendRate * t) * option.UnderlyingPrice * NormalDistribution.Phi(d1) - option.InterestRate * option.Strike * Math.Exp(-option.InterestRate * t) * NormalDistribution.Phi(d2); option.Rho = t * option.Strike * Math.Exp(-option.InterestRate * t) * NormalDistribution.Phi(d2); } else { option.OptionPrice = -option.UnderlyingPrice * NormalDistribution.Phi(-d1) + option.Strike * Math.Exp(-option.InterestRate * t) * NormalDistribution.Phi(-d2); option.Delta = Math.Exp(-option.DividendRate * t) * (NormalDistribution.Phi(d1) - 1); option.Theta = -Math.Exp(-option.DividendRate * t) * option.UnderlyingPrice * NormalDistribution.Density(d1) * option.Volatility / (2 * Math.Sqrt(t)) - option.DividendRate * Math.Exp(-option.DividendRate * t) * option.UnderlyingPrice * NormalDistribution.Phi(-d1) + option.InterestRate * option.Strike * Math.Exp(-option.InterestRate * t) * NormalDistribution.Phi(-d2); option.Rho = -t *option.Strike *Math.Exp(-option.InterestRate *t) * NormalDistribution.Phi(-d2); } option.Gamma = Math.Exp(-option.DividendRate * t) * NormalDistribution.Density(d1) / (option.UnderlyingPrice * option.Volatility * Math.Sqrt(t)); option.Vega = Math.Exp(-option.DividendRate * t) * option.UnderlyingPrice * NormalDistribution.Density(d1) * Math.Sqrt(t); SideHelper.FixGreeksAccordingToSide(option); }
public void Negate_ReturnsOptionPosition_WithSameSymbolAndNegativeQuantity() { var position = new OptionPosition(Symbols.SPY, 42); var negated = position.Negate(); Assert.AreEqual(position.Symbol, negated.Symbol); Assert.AreEqual(-position.Quantity, negated.Quantity); }
public void Initializes_OptionRight(PositionSide side) { // grab a random symbol and make it the correct right var quantity = (int)side; var position = new OptionPosition(Call[100], quantity); Assert.AreEqual(side, position.Side); }
public static TestCase ExtraPosition(OptionStrategyDefinition definition, params OptionPosition[] positions) { // add a random position w/ the same underlying var maxStrike = positions.Where(p => p.Symbol.HasUnderlying).Max(p => p.Strike); var extra = new OptionPosition(positions[0].Symbol.WithStrike(maxStrike + 5m), 1); var pos = positions.Concat(new[] {extra}).ToList(); return new TestCase(nameof(ExtraPosition), definition, pos, new[] {extra}, Array.Empty<OptionPosition>()); }
public void Initializes_OptionRight(OptionRight right) { // grab a random symbol and make it the correct right var symbol = Call[100].WithRight(right); var position = new OptionPosition(symbol, 1); Assert.AreEqual(right, position.Right); }
public void SubtractionOperator_SubtractsQuantity_WhenSymbolsMatch() { var left = new OptionPosition(Symbols.SPY, 42); var right = new OptionPosition(Symbols.SPY, 1); var sum = left - right; Assert.AreEqual(Symbols.SPY, sum.Symbol); Assert.AreEqual(41, sum.Quantity); }
public void AdditionOperator_AddsQuantity_WhenSymbolsMatch() { var left = new OptionPosition(Symbols.SPY, 42); var right = new OptionPosition(Symbols.SPY, 1); var sum = left + right; Assert.AreEqual(Symbols.SPY, sum.Symbol); Assert.AreEqual(43, sum.Quantity); }
public TestCase WithPosition(Symbol symbol, int quantity) { if (Position != default(OptionPosition)) { throw new InvalidOperationException($"Position has already been initialized: {Position}"); } Position = new OptionPosition(symbol, quantity); return(this); }
public void Compute(OptionPosition option) { // TODO : IMPLEMENT // option.OptionPrice = // option.Delta = // option.Gamma = // option.Vega = // option.Theta = // option.Rho = }
public void SubtractionOperator_ThrowsInvalidOperationException_WhenSymbolsDoNotMatch() { OptionPosition difference; var left = new OptionPosition(Symbols.SPY, 42); var right = new OptionPosition(Symbols.SPY_P_192_Feb19_2016, 1); Assert.Throws <InvalidOperationException>( () => difference = left - right ); }
public void AdditionOperator_DoesNotThrow_WhenOneSideEqualsDefault() { var value = new OptionPosition(Symbols.SPY, 42); var defaultValue = default(OptionPosition); var valueFirst = value + defaultValue; var defaultFirst = defaultValue + value; Assert.AreEqual(value, valueFirst); Assert.AreEqual(value, defaultFirst); }
public void AdditionOperator_ThrowsInvalidOperationException_WhenSymbolsDoNotMatch() { OptionPosition sum; var left = new OptionPosition(Symbols.SPY, 42); var right = new OptionPosition(Symbols.SPY_P_192_Feb19_2016, 1); Assert.Throws <InvalidOperationException>( () => sum = left + right ); }
private static string String(OptionPosition position) { var sign = position.Quantity > 0 ? "+" : ""; var s = position.Symbol; var symbol = s.HasUnderlying ? $"{s.Underlying.Value}:{s.ID.OptionRight}@{s.ID.StrikePrice}:{s.ID.Date:MM-dd}" : s.Value; return $"{sign}{position.Quantity} {symbol}"; }
public static OptionPosition FixGreeksAccordingToSide(OptionPosition option) { var sign = option.Side == Side.Buy ? 1 : -1; option.Delta *= sign; option.Gamma *= sign; option.Theta *= sign; option.Vega *= sign; option.Rho *= sign; return(option); }
public void Equality_IsDefinedUsing_SymbolAndQuantity() { var left = new OptionPosition(Symbols.SPY, 42); var right = new OptionPosition(Symbols.SPY, 42); Assert.AreEqual(left, right); Assert.IsTrue(left == right); right = right.Negate(); Assert.AreNotEqual(left, right); Assert.IsTrue(left != right); }
public void Compute(OptionPosition option) { int steps = option.TreeSteps; double s = option.UnderlyingPrice; var t = option.TimeToExpiry.TotalDays / 365.0; if (Math.Abs(t) < Double.Epsilon) { return; } if (option.TreeSteps == 0) { return; } var deltaT = t / (double)steps; if (deltaT >= Math.Pow(option.Volatility, 2) / Math.Pow(option.InterestRate - option.DividendRate, 2)) { return; } double u = Math.Exp(option.Volatility * Math.Sqrt(t)); double d = 1 / u; var prices = GetPrices(option.Type == OptionType.Call, option.UnderlyingPrice, t, steps, option.Volatility, option.Strike, option.InterestRate, option.DividendRate); // x x x // x x // x option.OptionPrice = prices[0, 0]; option.Delta = (prices[1, 1] - prices[1, 0]) / (s * u - s * d); option.Gamma = ((prices[2, 2] - prices[2, 1]) / (s * u * u - s * u * d) - (prices[2, 1] - prices[2, 0]) / (s * u * d - s * d * d)) / (0.5 * (s * u * u - s * d * d)); option.Theta = (prices[2, 1] - prices[0, 0]) / (2 * deltaT); option.Vega = (GetPrices(option.Type == OptionType.Call, option.UnderlyingPrice, t, steps, option.Volatility * 1.01, option.Strike, option.InterestRate, option.DividendRate)[0, 0] - option.OptionPrice) / (option.Volatility * 0.01); option.Rho = (GetPrices(option.Type == OptionType.Call, option.UnderlyingPrice, t, steps, option.Volatility, option.Strike, option.InterestRate * 1.01, option.DividendRate)[0, 0] - option.OptionPrice) / (option.InterestRate * 0.01); SideHelper.FixGreeksAccordingToSide(option); }
public void IsEmpty_ReturnsTrue_WhenCountIsZero(int count) { var positions = OptionPositionCollection.Empty; for (int i = 0; i < count; i++) { var position = new OptionPosition(Call[100 + i], 1 + i); positions = positions.Add(position); } Assert.AreEqual(count, positions.Count); Assert.AreEqual(count == 0, positions.IsEmpty); }
public void MultiplyOperator_ScalesQuantity() { const int factor = 2; var position = new OptionPosition(Symbols.SPY, 42); var positionFirst = position * factor; Assert.AreEqual(position.Symbol, positionFirst.Symbol); Assert.AreEqual(factor * 42, positionFirst.Quantity); var factorFirst = factor * position; Assert.AreEqual(positionFirst, factorFirst); }
public void Compute(OptionPosition option) { var t = option.TimeToExpiry.TotalDays / 365.0; if (Math.Abs(t) < Double.Epsilon) { return; } if (option.TreeSteps == 0) { return; } Func <double, double> getWithTime = x => GetPrice(option.Type == OptionType.Call, option.UnderlyingPrice, option.Strike, option.Volatility, option.InterestRate, option.DividendRate, x, option.TreeSteps)[0, 0]; Func <double, double> getWithVol = x => GetPrice(option.Type == OptionType.Call, option.UnderlyingPrice, option.Strike, x, option.InterestRate, option.DividendRate, t, option.TreeSteps)[0, 0]; Func <double, double> getWithR = x => GetPrice(option.Type == OptionType.Call, option.UnderlyingPrice, option.Strike, option.Volatility, x, option.DividendRate, t, option.TreeSteps)[0, 0]; var deltaT = t / (double)option.TreeSteps; double u = Math.Exp(option.Volatility * Math.Sqrt(2 * deltaT)); double d = Math.Exp(-option.Volatility * Math.Sqrt(2 * deltaT)); var prices = GetPrice(option.Type == OptionType.Call, option.UnderlyingPrice, option.Strike, option.Volatility, option.InterestRate, option.DividendRate, t, option.TreeSteps); option.OptionPrice = prices[0, 0]; option.Delta = (prices[1, 2] - 2 * prices[1, 1] + prices[1, 0]) / (option.UnderlyingPrice * (u - d)); option.Gamma = ((prices[2, 4] - 2 * prices[2, 3] + prices[2, 2]) / (Math.Pow(option.UnderlyingPrice * (u * u - u), 2)) - (prices[2, 2] - 2 * prices[2, 1] + prices[2, 0]) / (Math.Pow(option.UnderlyingPrice * (d - d * d), 2))) / (0.5 * (option.UnderlyingPrice * (u * u - d * d))); option.Theta = (getWithTime(t + deltaT) - getWithTime(t - deltaT)) / (2 * deltaT); double volDelta = option.Volatility * 0.01; option.Vega = (getWithVol(option.Volatility + volDelta) - getWithVol(option.Volatility - volDelta)) / (2 * volDelta); double rDelta = option.InterestRate * 0.01; option.Rho = (getWithR(option.InterestRate + rDelta) - getWithR(option.InterestRate - rDelta)) / (2 * rDelta); SideHelper.FixGreeksAccordingToSide(option); }
internal static EOptionPosition SOptionPosition(OptionPosition x) { switch (x) { case OptionPosition.InTheMoney: return EOptionPosition.InTheMoney; case OptionPosition.AtTheMoney: return EOptionPosition.AtTheMoney; case OptionPosition.OutOfTheMoney: return EOptionPosition.OutOfTheMoney; default: throw new NotSupportedException(); } }
public PricingShellViewModel() { _currentOption = new OptionPosition(); OptionStyles = new ObservableCollection <OptionStyle>(Enum.GetValues(typeof(OptionStyle)).Cast <OptionStyle>()); OptionExerciseTypes = new ObservableCollection <OptionExerciseType>( Enum.GetValues(typeof(OptionExerciseType)).Cast <OptionExerciseType>()); OptionTypes = new ObservableCollection <OptionType>(Enum.GetValues(typeof(OptionType)).Cast <OptionType>()); PricingModels = new ObservableCollection <OptionPricingModel>( Enum.GetValues(typeof(OptionPricingModel)).Cast <OptionPricingModel>()); computeThis(); OptionsPortfolio.CollectionChanged += (sender, args) => computePortfolio(); }
public void Compute(OptionPosition option) { // initialise option parameters double S = option.UnderlyingPrice; double K = option.Strike; double sigma = option.Volatility; double r = option.InterestRate; double q = option.DividendRate; OptionType type = option.Type; OptionExerciseType exerciseType = option.ExerciseType; int nPriceSteps, nTimeSteps; // number of price and time steps in the lattice nPriceSteps = 300; double S_max = 2 * K; double dS = S_max / nPriceSteps; double t = option.TimeToExpiry.Days / 365.0; double dt = 0.9 / sigma / sigma / nPriceSteps / nPriceSteps; // for stability nTimeSteps = (int) Math.Floor(t / dt) + 1; dt = t / nTimeSteps; // interval between time steps double[,] optionPrice = createLattice(S, K, sigma, r, q, type, exerciseType, nTimeSteps, dt, nPriceSteps, dS); var sign = option.Side == Side.Buy ? 1 : -1; // find index such that S lies in [ index * dS, (index + 1) * dS ] int index = (int)Math.Floor(S / dS); double price = 0; // run 2-point Lagrange polynomial interpolation price = price + (S - dS * (index + 1)) / (dS * index - dS * (index + 1)) * optionPrice[0, index]; price = price + (S - dS * index) / (dS * (index + 1) - dS * (index)) * optionPrice[0, index + 1]; option.OptionPrice = price; option.Delta = sign * (optionPrice[0, index + 1] - optionPrice[0, index - 1]) / (2 * dS); option.Gamma = sign * (optionPrice[0, index + 1] - 2 * optionPrice[0, index] + optionPrice[0, index - 1]) / (dS * dS); option.Theta = (optionPrice[1, index] - optionPrice[0, index]) / dt; double delta = 0.001; double[,] priceDeltaVol = createLattice(S, K, (sigma + delta), r, q, type, exerciseType, nTimeSteps, dt, nPriceSteps, dS); // option price with a higher volatily for vega calculation price = (S - dS * (index + 1)) / (dS * index - dS * (index + 1)) * priceDeltaVol[0, index] + (S - dS * index) / (dS * (index + 1) - dS * (index)) * priceDeltaVol[0, index + 1]; // interpolate option.Vega = sign * (price - option.OptionPrice) / delta; // estimate option price sensitivity to volatility double[,] priceDeltaR = createLattice(S, K, sigma, (r + delta), q, type, exerciseType, nTimeSteps, dt, nPriceSteps, dS); // option price with a higher rate for rho calculation price = (S - dS * (index + 1)) / (dS * index - dS * (index + 1)) * priceDeltaR[0, index] + (S - dS * index) / (dS * (index + 1) - dS * (index)) * priceDeltaR[0, index + 1]; // interpolate option.Rho = sign * (price - option.OptionPrice) / delta; // estimate option price sensitivity to percent rate }
private OptionPosition _Option(Option.Type optionType, double strikeLevel, double spotAtStrikeDate, DateTime maturity, DateTime tradeDate) { // Instanciate OptionPosition optionPosition = new OptionPosition(Payoff(optionType, strikeLevel) as StrikedTypePayoff, Exercise(maturity), tradeDate, spotAtStrikeDate, _dayCounter); // Set internal properties: // Levels optionPosition._strikeLevel = strikeLevel; optionPosition._spotAtStrike = spotAtStrikeDate; // Dates // optionPosition.expiryDate = maturity; // optionPosition.tradeDate = tradeDate; // Return return(optionPosition); }
internal static EOptionPosition SOptionPosition(OptionPosition x) { switch (x) { case OptionPosition.InTheMoney: return(EOptionPosition.InTheMoney); case OptionPosition.AtTheMoney: return(EOptionPosition.AtTheMoney); case OptionPosition.OutOfTheMoney: return(EOptionPosition.OutOfTheMoney); default: throw new NotSupportedException(); } }
public void Compute(OptionPosition option) { // initialise option parameters double S = option.UnderlyingPrice; double K = option.Strike; double sigma = option.Volatility; double r = option.InterestRate; double q = option.DividendRate; OptionType type = option.Type; OptionExerciseType exerciseType = option.ExerciseType; int nSteps = 1000; // number of steps in the binomial model double t = option.TimeToExpiry.Days / 365.0; double dt = t / nSteps; // time interval between steps double[,] lattice = createLattice(S, K, sigma, r, q, type, exerciseType, nSteps, dt); var sign = option.Side == Side.Buy ? 1 : -1; double upFactor = Math.Pow(Math.E, sigma * Math.Sqrt(dt)); double downFactor = 1 / upFactor; option.OptionPrice = lattice[0, 0]; option.Delta = sign * (lattice[1, 1] - lattice[1, 0]) / (option.UnderlyingPrice * (upFactor - downFactor)); option.Gamma = sign * (((lattice[2, 2] - lattice[2, 1]) / (option.UnderlyingPrice * (upFactor * upFactor - upFactor * downFactor))) - ((lattice[2, 1] - lattice[2, 0]) / (option.UnderlyingPrice * (upFactor * downFactor - downFactor * downFactor)))) / (0.5 * option.UnderlyingPrice * (upFactor * upFactor - downFactor * downFactor)); option.Theta = sign * (lattice[2, 1] - lattice[0, 0]) / (2 * dt); double delta = 0.001; double priceDeltaVol = createLattice(S, K, (sigma + delta), r, q, type, exerciseType, nSteps, dt)[0, 0]; // option price with a higher volatily for vega calculation option.Vega = sign * (priceDeltaVol - option.OptionPrice) / delta; // estimate option price sensitivity to volatility double priceDeltaR = createLattice(S, K, sigma, (r + delta), q, type, exerciseType, nSteps, dt)[0, 0]; // option price with a higher rate for rho calculation option.Rho = sign * (priceDeltaR - option.OptionPrice) / delta; // estimate option price sensitivity to percent rate }
public static Stock CreateStock(EquityVolCalcTestData.Stock stock) { DateTime today = XmlGetDate(stock.Date); decimal spot = Convert.ToDecimal(stock.Spot); DateTime baseDate = XmlGetDate(stock.RateCurve.BaseDate); DateTime[] rateDates = XmlGetDateArray(stock.RateCurve.DateArray); //Load rate curve String tp = stock.RateCurve.RateType; var rc = new RateCurve(stock.RateCurve.Ccy, tp, baseDate, rateDates, stock.RateCurve.RateArray); // Load dividends var divs = (from div in stock.Dividends let exDate = XmlGetDate(div.ExDate) select new Dividend(exDate, Convert.ToDecimal(div.Amount))).ToList(); //Load stock object var stock0 = new Stock(today, spot, stock.AssetId, stock.Name, rc, divs); var vol0 = new VolatilitySurface(stock.AssetId, spot, today); //Load vols stock0.VolatilitySurface = vol0; foreach (StockVolatilitySurfaceForwardExpiry exp in stock.VolatilitySurface.Expiries) { DateTime expDate = XmlGetDate(exp.ExpiryDate); Decimal fwd = Convert.ToDecimal(exp.FwdPrice); var exp0 = new ForwardExpiry(expDate, fwd); // exp0.NodalPoint = System.Convert.ToBoolean(exp.NodalPoint); vol0.AddExpiry(exp0); foreach (StockVolatilitySurfaceForwardExpiryStrike str in exp.Strikes) { var call = new OptionPosition(); var put = new OptionPosition(); double strikeprice0 = Convert.ToDouble(str.StrikePrice); var str0 = new Strike(strikeprice0, call, put, Units.Cents) { Moneyness = Convert.ToDouble(str.Moneyness) }; exp0.AddStrike(str0, true); var vp = new VolatilityPoint(); decimal vol = Convert.ToDecimal(str.Volatility.Value); vp.SetVolatility(vol, VolatilityState.Default()); str0.SetVolatility(vp); } } return(stock0); }
public void CreatesStrikePredicate() { var predicate = OptionStrategyLegPredicate.Create( (legs, p) => p.Strike < legs[0].Strike ); var position = new OptionPosition(Put[95m], 1); var positiveSet = new List <OptionPosition> { new OptionPosition(Put[100m], 1) }; Assert.IsTrue(predicate.Matches(positiveSet, position)); var negativeSet = new List <OptionPosition> { new OptionPosition(Put[90m], 1) }; Assert.IsFalse(predicate.Matches(negativeSet, position)); }
private void ShowExample(object obj) { OptionsPortfolio.Clear(); var option1 = new OptionPosition { ExpirationDateTime = DateTime.Now.AddYears(1), Strike = 90, Type = OptionType.Put, Side = Side.Buy, Id = _idCounter++, Quantity = 1 }; option1.PropertyChanged += EvaluatePortfolio; var option2 = new OptionPosition { Strike = 100, Type = OptionType.Call, Side = Side.Sell, Id = _idCounter++, Quantity = 1 }; option2.PropertyChanged += EvaluatePortfolio; option1.Compute(); option2.Compute(); option1.CostPrice = option1.PositionPrice; option2.CostPrice = option2.PositionPrice; OptionsPortfolio.Add(option1); OptionsPortfolio.Add(option2); }
public void Compute(OptionPosition option) { var t = option.TimeToExpiry.Days / 365.0; // var d1 = // var d2 = var sign = option.Side == Side.Buy ? 1 : -1; // when calculating option greeks keep in mind that we calculate greek for position, // and that's why BS formulas for greeks must be multiplied by -1 in case we're selling options // so formulas for greeks are [sign * BSFormula] if (option.Type == OptionType.Call) { // option.OptionPrice = //option.Delta = //option.Theta = option.Rho = 555; } //option.Gamma = //option.Vega = }
public static TestCase MissingPosition(OptionStrategyDefinition definition, OptionPosition missing, params OptionPosition[] positions) { return new TestCase(nameof(MissingPosition), definition, positions, Array.Empty<OptionPosition>(), new []{missing}); }