Parent: Object
OptionSynthetic is a static utility class that generates synthetic option symbols and calculated option price histories. It also provides methods for calculating option prices and Greeks using the Black-Scholes model. Synthetic option calculations require an estimate of implied volatility (IV). The resulting prices and Greeks will only approximate actual option values to the extent that the supplied IV accurately represents the option's implied volatility. OptionSynthetic is particularly useful when developing and backtesting option trading strategies when historical option contracts or option chains are not available.
Calculates a hypothetical option price using the Black-Scholes model. Pass the option contract symbol in optionSymbol, the estimated implied volatility in impliedVolatility, the hypothetical underlying price in priceUnderlying, and the date/time for which the calculation should be performed in dateTime. If dateTime is on or after the option's expiration, the method returns the option's intrinsic value instead of a Black-Scholes calculated value.
using WealthLab.Backtest; using WealthLab.Core; using WealthLab.Data; namespace WealthScript { public class MyStrategy : UserStrategyBase { public override void Initialize(BarHistory bars) { double iv = 0.25; DateTime exDate = bars.NextOptionExpiryDate(bars.Count - 1); //ATM call for next monthly expiration string atmCall = OptionSynthetic.GetOptionsSymbol( bars, OptionType.Call, bars.LastValue, bars.EndDate, 1); //calculate its value with the stock 10% higher, //one week before expiration double stkPrice = bars.LastValue * 1.1; double optionPrice = OptionSynthetic.CalculateOptionPrice( atmCall, iv, stkPrice, exDate.AddDays(-7)); DrawHeaderText( $"{atmCall} value on {exDate.AddDays(-7):yyyy-MM-dd}", WLColor.NeonGreen, 14); DrawHeaderText( $"for {bars.Symbol} at {stkPrice:N2} is {optionPrice:N2}", WLColor.NeonGreen, 14); } public override void Execute(BarHistory bars, int idx) { } } }
Calculates option Greeks for the specified bar of the underlying BarHistory and returns the results in an OptionGreek instance. The calculated values include OptionPrice, Delta, Theta, Gamma, and Vega. The method uses the Black-Scholes model and the supplied iv as the option's implied volatility estimate.
using WealthLab.Backtest; using WealthLab.Core; using WealthLab.Data; using WealthLab.Indicators; namespace WealthScript { public class OptionSyntheticGreeks : UserStrategyBase { public override void Initialize(BarHistory bars) { //estimate a varying IV using a factor of HV TimeSeries iv = HV.Series(bars.Close, 89, 144) / 100d; string symbol = OptionSynthetic.GetOptionsSymbol( bars, OptionType.Call, bars.Close.LastValue, bars.DateTimes[bars.Count - 1], 3); _osyn = OptionSynthetic.GetHistory(bars, symbol, iv); PlotBarHistory(_osyn, "OSYN", WLColor.Cyan); //Greeks at the last bar OptionGreek og = OptionSynthetic.GetGreeks( bars, bars.Count - 1, symbol, iv.LastValue); DrawHeaderText(og.Symbol + ": " + og.OptionPrice.ToString("$0.00"), WLColor.Cyan, 12, "OSYN"); DrawHeaderText("Delta: " + og.Delta.ToString("N2"), WLColor.Cyan, 12, "OSYN"); DrawHeaderText("Theta: " + og.Theta.ToString("N2"), WLColor.Cyan, 12, "OSYN"); DrawHeaderText("Gamma: " + og.Gamma.ToString("N2"), WLColor.Cyan, 12, "OSYN"); DrawHeaderText("Vega: " + og.Vega.ToString("N2"), WLColor.Cyan, 12, "OSYN"); } public override void Execute(BarHistory bars, int idx) { } private BarHistory _osyn; } }
Returns a calculated BarHistory representing a synthetic option contract. The synthetic option's OHLC values are calculated from the corresponding OHLC values of the underlier using the Black-Scholes model. You can supply either a constant implied volatility or a TimeSeries containing a varying implied volatility estimate. When using an optionSymbol overload, OptionSynthetic parses the option type, strike, and expiration from the supplied symbol. The resulting synthetic BarHistory is cached in the underlying BarHistory's Cache using the synthetic option symbol as the key.
using WealthLab.Backtest; using WealthLab.Core; using WealthLab.Data; namespace WealthScript { public class SyntheticOptionBars : UserStrategyBase { public override void Initialize(BarHistory bars) { //get the Put with the closest strike to the last chart value string symbol = OptionSynthetic.GetOptionsSymbol( bars, OptionType.Put, bars.Close.LastValue, bars.DateTimes[bars.Count - 1], 3); //create and plot the synthetic option history _osyn = OptionSynthetic.GetHistory(bars, symbol, 0.2); PlotBarHistory(_osyn, "OSYN", WLColor.LightCyan); } public override void Execute(BarHistory bars, int idx) { } private BarHistory _osyn; } }
Generates a synthetic option contract symbol based on the supplied underlying BarHistory, option type, price, and expiration criteria. Pass OptionType.Call or OptionType.Put in optionType. The price parameter represents the price near the desired strike. Unless priceIsStrike is true, OptionSynthetic converts this value to an appropriate synthetic strike using the following increments: | Underlying Price | Strike Increment | | --- | --- | | Above $1,000 | $25 | | Above $200 | $10 | | Above $10 | $5 | | $10 or below | $1 | If closestStrike is true, the strike closest to price is selected. If false, the next higher strike is selected for calls and the next lower strike for puts. Set priceIsStrike to true to use price directly as the strike without adjustment. The expiration is determined from currentDate, minDaysAhead, and useWeeklies. Set allowExpired to true when backtesting synthetic options so historical expiration dates can be generated.
using WealthLab.Backtest; using WealthLab.Core; using WealthLab.Data; namespace WealthScript { public class SyntheticOptionSymbol : UserStrategyBase { public override void Initialize(BarHistory bars) { double price = bars.Close[bars.Count - 1]; DateTime currentDate = bars.DateTimes[bars.Count - 1]; string optSym = OptionSynthetic.GetOptionsSymbol( bars, OptionType.Call, price, currentDate, minDaysAhead: 0, useWeeklies: false, allowExpired: true, closestStrike: true); DrawHeaderText("ATM Call: " + optSym, WLColor.NeonGreen, 14); } public override void Execute(BarHistory bars, int idx) { } } }
Parses optionSymbol and returns its expiration date. This method is obsolete. Use OptionsHelper.SymbolExpiry instead.
Parses optionSymbol and returns its strike price. This method is obsolete. Use OptionsHelper.SymbolStrike instead.
Attempts to calculate implied volatility using an iterative Newton-Raphson calculation. The current implementation is marked in the source code as not yet accurate and needing further work. It should therefore not be relied upon for precise implied volatility calculations.
Returns a synthetic option symbol for the specified underlying BarHistory, option type, strike, and expiration.
Synthetic option symbols begin with ! and use the following format:
![underlier]yyMMdd[C/P][strike]
For example:
!SPY260918C650
The Symbol method lets you specify the strike and expiration exactly, whereas GetOptionsSymbol determines them according to its strike and expiration selection rules.
using WealthLab.Backtest; using WealthLab.Core; using WealthLab.Data; namespace WealthScript { public class SyntheticOptionSymbol : UserStrategyBase { public override void Initialize(BarHistory bars) { double strike = Math.Floor(bars.LastValue / 5) * 5; DateTime expiry = bars.DateTimes[bars.Count - 1] .AddDays(3) .NextOptionExpiryDate(bars); string symbol = OptionSynthetic.Symbol( bars, OptionType.Call, strike, expiry); DrawHeaderText(symbol, WLColor.Gold, 12, "Price"); } public override void Execute(BarHistory bars, int idx) { } } }