private static void UpdateContract(OptionContract contract, Tick tick) { if (tick.TickType == TickType.Trade) { contract.LastPrice = tick.Price; } else if (tick.TickType == TickType.Quote) { if (tick.AskPrice != 0m) { contract.AskPrice = tick.AskPrice; contract.AskSize = (long)tick.AskSize; } if (tick.BidPrice != 0m) { contract.BidPrice = tick.BidPrice; contract.BidSize = (long)tick.BidSize; } } else if (tick.TickType == TickType.OpenInterest) { if (tick.Value != 0m) { contract.OpenInterest = tick.Value; } } }
private OptionData GenerateOptionInPreconditions(EOptionType optionType) { double theta = MINIMAL_THETA + 1; DateTime expiry = DateTime.Now.Add(TimeSpan.FromDays(MIN_EXPIRY_DAYS + 1)); double strike; double underline = 100; if (optionType == EOptionType.Call) { strike = underline * (1 + MINIMAL_DIS_UNL / 100) + 10; } else { strike = underline * (1 - MINIMAL_DIS_UNL / 100) - 10; } var optionContract = new OptionContract("AAPL", expiry, optionType) { Strike = strike }; var option = new OptionData() { UnderlinePrice = underline, Theta = theta, OptionContract = optionContract }; return(option); }
/// <summary> /// calculate the option's premium /// </summary> private void btnCalc_Click(object sender, EventArgs e) { if (prices.Count < 3) { return; } var contract = new OptionContract { Side = cbSide.SelectedIndex == 0 ? Side.Put : Side.Call, Price = tbPrice.Text.Replace(',', '.').Replace(" ", "").ToDoubleUniform(), Strike = tbStrike.Text.Replace(',', '.').Replace(" ", "").ToDoubleUniform(), Term = tbTerm.Text.Replace(',', '.').Replace(" ", "").ToDoubleUniform(), Volume = tbVolume.Text.Replace(',', '.').Replace(" ", "").ToDoubleUniform(), YearTradeDays = tbDaysInYear.Text.ToInt() }; var calc = new Calculator { iterationsCount = tbIterations.Text.ToInt() }; var prem = calc.CalcPremium(prices, cbDetrend.Checked, contract, ExecutablePath.ExecPath); tbPremium.Text = $"{prem:F4}"; tbHv.Text = $"{calc.HV:F4}"; }
public decimal FindMaxPain(QCAlgorithmFramework algorithm, OptionChain chain) { //get all ITM var options = GetOptionsForExpiry(algorithm, chain.Underlying.Symbol, 0); var calls = options.Where((o) => o.Right == OptionRight.Call && o.Strike < chain.Underlying.Price) .OrderBy((o) => o.Strike); var puts = options.Where((o) => o.Right == OptionRight.Put && o.Strike > chain.Underlying.Price) .OrderBy((o) => - o.Strike); //walk up the chain until both sides balance int openCalls = 0; int openPuts = 0; List <int> runningCalls = new List <int>(); List <int> runningPuts = new List <int>(); OptionContract largestBidOption = null; int pi = 0; //put incrementor for (int ci = 0; ci < calls.Count() && pi < puts.Count(); ci++) { var call = calls.Skip(ci).First(); var put = puts.Skip(pi++).First(); if (Math.Round((put.Strike - chain.Underlying.Price)) > Math.Round((chain.Underlying.Price - call.Strike))) { //try again, re-align ci--; continue; } //TODO: OpenInterest????!!!!!!!!!!!!!!!!! openCalls += (int)call.BidSize; openPuts += (int)put.BidSize; runningCalls.Add(openCalls); runningPuts.Add(openPuts); //for now, doing a hack where it finds the option contract with the most interest (largest bid size) if (largestBidOption == null) { largestBidOption = call; } if (call.BidSize > largestBidOption.BidSize) { largestBidOption = call; } if (put.BidSize > largestBidOption.BidSize) { largestBidOption = put; } } if (largestBidOption == null) { return(0); } return(largestBidOption.Strike); }
private static void UpdateContract(OptionContract contract, TradeBar tradeBar) { if (tradeBar.Close == 0m) { return; } contract.LastPrice = tradeBar.Close; contract.Volume = (long)tradeBar.Volume; }
public void BlackScholesPortfolioTest() { const decimal price = 20.00m; const decimal underlyingPrice = 200m; const decimal underlyingVol = 0.15m; const decimal riskFreeRate = 0.01m; var tz = TimeZones.NewYork; var evaluationDate = new DateTime(2015, 2, 19); var SPY_C_192_Feb19_2016E = Symbol.CreateOption("SPY", Market.USA, OptionStyle.European, OptionRight.Call, 192m, new DateTime(2016, 02, 19)); // setting up underlying var equity = new Equity( SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false), new Cash(Currencies.USD, 0, 1m), SymbolProperties.GetDefault(Currencies.USD), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null ); equity.SetMarketPrice(new Tick { Value = underlyingPrice }); equity.VolatilityModel = new DummyVolatilityModel(underlyingVol); // setting up European style option var contract = new OptionContract(SPY_C_192_Feb19_2016E, Symbols.SPY) { Time = evaluationDate }; var optionCall = new Option( SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), SPY_C_192_Feb19_2016E, Resolution.Minute, tz, tz, true, false, false), new Cash(Currencies.USD, 0, 1m), new OptionSymbolProperties(SymbolProperties.GetDefault(Currencies.USD)), ErrorCurrencyConverter.Instance, RegisteredSecurityDataTypesProvider.Null ); optionCall.SetMarketPrice(new Tick { Value = price }); optionCall.Underlying = equity; // running evaluation var priceModel = OptionPriceModels.BlackScholes(); var results = priceModel.Evaluate(optionCall, null, contract); var callPrice = results.TheoreticalPrice; var greeks = results.Greeks; // BS equation var rightPart = greeks.Theta + riskFreeRate * underlyingPrice * greeks.Delta + 0.5m * underlyingVol * underlyingVol * underlyingPrice * underlyingPrice * greeks.Gamma; var leftPart = riskFreeRate * callPrice; Assert.AreEqual((double)leftPart, (double)rightPart, 0.0001); }
// // Get ATM call and put // public virtual void get_contracts(Slice slice) { LogCust("called get contracts"); foreach (var kvp in slice.OptionChains) { if (kvp.Key != this.option_symbol) { continue; } var chain = kvp.Value; var spot_price = chain.Underlying.Price; // self.Log("spot_price {}" .format(spot_price)) // prefer to do in steps, rather than a nested sorted // 1. get furthest expiry var contracts_by_T = chain.OrderByDescending(x => x.Expiry).ToList(); if (!(contracts_by_T.Count > 0)) { return; } this.expiry = contracts_by_T[0].Expiry.Date; var weeklySymbol = QuantConnect.Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Call, 200, this.expiry); //var monthlysymbol = Symbol.CreateOption("SPY", Market.USA, OptionStyle.American, OptionRight.Call, 200, new DateTime(2020, 04, 17)); //Assert.True(OptionSymbol.IsWeekly(weeklySymbol)); //Assert.False(OptionSymbol.IsWeekly(monthlysymbol)); //Assert.AreEqual(new DateTime(2020, 04, 17)/*Friday*/, OptionSymbol.GetLastDayOfTrading(monthlysymbol)); //Good Friday on 10th so should be 9th //Assert.AreEqual(new DateTime(2020, 04, 09)/*Thursday*/, OptionSymbol.GetLastDayOfTrading(weeklySymbol)); //this.last_trading_day = last_trading_day(this.expiry); this.last_trading_day = OptionSymbol.GetLastDayOfTrading(weeklySymbol); // get contracts with further expiry and sort them by strike var slice_T = (from i in chain where i.Expiry.Date == this.expiry select i).ToList(); var sorted_contracts = slice_T.OrderBy(x => x.Strike).ToList(); // self.Log("Expiry used: {} and shortest {}" .format(self.expiry, contracts_by_T[-1].Expiry.date()) ) // 2a. get the ATM closest CALL to short var calls = (from i in sorted_contracts where i.Right == OptionRight.Call && i.Strike >= spot_price select i).ToList(); //this.call = calls ? calls[0] : null; this.call = calls.Count > 0 ? calls.First() : null; // self.Log("delta call {}, self.call type {}" .format(self.call.Greeks.Delta, type(self.call))) // self.Log("implied vol {} " .format(self.call.ImpliedVolatility)) // 2b. get the ATM closest put to short var puts = (from i in sorted_contracts where i.Right == OptionRight.Put && i.Strike <= spot_price select i).ToList(); this.put = puts.Count > 0 ? puts.Last() : null; //if (put == null) this.Quit("put == null"); } }
public Market Market(OptionContract instrument) { if (this._markets.ContainsKey(instrument.ID)) { return(this._markets[instrument.ID]); } else { return(null); } }
private static void UpdateContract(OptionContract contract, QuoteBar quote) { if (quote.Ask != null && quote.Ask.Close != 0m) { contract.AskPrice = quote.Ask.Close; contract.AskSize = (long)quote.LastAskSize; } if (quote.Bid != null && quote.Bid.Close != 0m) { contract.BidPrice = quote.Bid.Close; contract.BidSize = (long)quote.LastBidSize; } }
public static bool IsOTM(this OptionContract pContract, decimal pUnderlyingPrice) { if (pContract.Right == OptionRight.Put) { return((pUnderlyingPrice - pContract.Strike) > 0); } else if (pContract.Right == OptionRight.Call) { return((pContract.Strike - pUnderlyingPrice) > 0); } return(false); }
public override void Initialize() { this.SetStartDate(2017, 1, 1); this.SetEndDate(2017, 6, 28); this.SetCash(25000); this.LogCust("PERIOD: 2017"); // ---------------------------------------------------------------------- // Algo params // ---------------------------------------------------------------------- this.PREMIUM = 0.01; this.MAX_EXPIRY = 30; this._no_K = 2; this.resol = Resolution.Minute; this.tkr = SPY; // self.Ntnl_perc = d.Decimal( round( 1. / (2. * self.MAX_EXPIRY/7.), 2) ) # notional percentage, e.g. 0.08 this.select_flag = false; this.hedge_flag = false; this.previous_delta = 0.0; this.delta_treshold = 0.05; // ---------------------------------------------------------------------- // add underlying Equity var equity = this.AddEquity(this.tkr, this.resol); equity.SetDataNormalizationMode(DataNormalizationMode.Raw); this.equity_symbol = equity.Symbol; // Add options var option = this.AddOption(this.tkr, this.resol); this.option_symbol = option.Symbol; // set our strike/expiry filter for this option chain option.SetFilter(this.UniverseFunc); // for greeks and pricer (needs some warmup) - https://github.com/QuantConnect/Lean/blob/21cd972e99f70f007ce689bdaeeafe3cb4ea9c77/Common/Securities/Option/OptionPriceModels.cs#L81 option.PriceModel = OptionPriceModels.CrankNicolsonFD(); // this is needed for Greeks calcs this.SetWarmUp(TimeSpan.FromDays(3)); this._assignedOption = false; this.call = null; this.put = null; OrderTickets.Add(new OrderTicketInfo { EquityUnderlying = equity }); OrderTickets.Add(new OrderTicketInfo { EquityUnderlying = equity }); // ----------------------------------------------------------------------------- // scheduled functions // ----------------------------------------------------------------------------- this.Schedule.On(this.DateRules.EveryDay(this.equity_symbol), this.TimeRules.AfterMarketOpen(this.equity_symbol, 60), new Action(this.close_optionsOpen)); this.Schedule.On(this.DateRules.EveryDay(this.equity_symbol), this.TimeRules.BeforeMarketClose(this.equity_symbol, 10), new Action(this.close_optionsClose)); }
/// <summary> /// Returns current estimate of the underlying volatility /// </summary> /// <param name="security">The option security object</param> /// <param name="slice">The current data slice. This can be used to access other information /// available to the algorithm</param> /// <param name="contract">The option contract to evaluate</param> /// <returns>The estimate</returns> public double Estimate(Security security, Slice slice, OptionContract contract) { var option = security as Option; if (option != null && option.Underlying != null && option.Underlying.VolatilityModel != null && option.Underlying.VolatilityModel.Volatility > 0m) { return((double)option.Underlying.VolatilityModel.Volatility); } return(0.0); }
public void PutCallParityTest() { const decimal underlyingPrice = 200m; const decimal underlyingVol = 0.15m; const decimal riskFreeRate = 0.01m; var tz = TimeZones.NewYork; var evaluationDate = new DateTime(2015, 2, 19); var SPY_C_192_Feb19_2016E = Symbol.CreateOption("SPY", Market.USA, OptionStyle.European, OptionRight.Call, 192m, new DateTime(2016, 02, 19)); var SPY_P_192_Feb19_2016E = Symbol.CreateOption("SPY", Market.USA, OptionStyle.European, OptionRight.Put, 192m, new DateTime(2016, 02, 19)); // setting up underlying var equity = new Equity(SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency)); equity.SetMarketPrice(new Tick { Value = underlyingPrice }); equity.VolatilityModel = new DummyVolatilityModel(underlyingVol); // setting up European style call option var contractCall = new OptionContract(SPY_C_192_Feb19_2016E, Symbols.SPY) { Time = evaluationDate }; var optionCall = new Option(SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), SPY_C_192_Feb19_2016E, Resolution.Minute, tz, tz, true, false, false), new Cash(CashBook.AccountCurrency, 0, 1m), new OptionSymbolProperties(SymbolProperties.GetDefault(CashBook.AccountCurrency))); optionCall.Underlying = equity; // setting up European style put option var contractPut = new OptionContract(SPY_P_192_Feb19_2016E, Symbols.SPY) { Time = evaluationDate }; var optionPut = new Option(SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), SPY_P_192_Feb19_2016E, Resolution.Minute, tz, tz, true, false, false), new Cash(CashBook.AccountCurrency, 0, 1m), new OptionSymbolProperties(SymbolProperties.GetDefault(CashBook.AccountCurrency))); optionPut.Underlying = equity; // running evaluation var priceModel = OptionPriceModels.BlackScholes(); var resultsCall = priceModel.Evaluate(optionCall, null, contractCall); var resultsPut = priceModel.Evaluate(optionPut, null, contractPut); var callPrice = resultsCall.TheoreticalPrice; var putPrice = resultsPut.TheoreticalPrice; // Put-call parity equation var rightPart = putPrice + underlyingPrice; // no yield var leftPart = callPrice + contractCall.Strike * (decimal)Math.Exp((double)-riskFreeRate); Assert.AreEqual((double)leftPart, (double)rightPart, 0.0001); }
public void closeOptionsClose() { this.LogCust("On last trading day: liquidate options with value and underlying "); // liquidate options (if invested and in the money [otherwise their price is min of $0.01) Liquid(); this.call = null; this.put = null; OrderTickets.Clear(); OrderTickets.Add(new OrderTicketInfo2 { EquityUnderlying = equity }); OrderTickets.Add(new OrderTicketInfo2 { EquityUnderlying = equity }); }
/// <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 void TradeOptionContract(OptionContract contract) { if (contract == null || contract.BidPrice == 0) { return; } int totalPrice = TRADE_PER_SYMBOL / 2; decimal price = (contract.BidPrice + contract.AskPrice) / 2; int quantity = (int)Math.Floor(totalPrice / price); if (quantity > 0 && price > 0) { LimitOrder(contract.Symbol, quantity, price); } }
private bool CheckExist(OptionContract newOption) { var optionList = dataReceiver.GetAllOptions(); var result = optionList.FirstOrDefault(option => option.OptionType == newOption.OptionType && option.Strike == newOption.Strike && option.Maturity == newOption.Maturity); if (result == null) { return(true); } else { existWarningLabel.Visibility = Visibility.Visible; existWarningLabel.Content = "Option is already in the market"; return(false); } }
public void GreekApproximationTest() { const decimal price = 20.00m; const decimal underlyingPrice = 190m; const decimal underlyingVol = 0.15m; var tz = TimeZones.NewYork; var evaluationDate = new DateTime(2016, 1, 19); var equity = new Equity(SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency)); equity.SetMarketPrice(new Tick { Value = underlyingPrice }); equity.VolatilityModel = new DummyVolatilityModel(underlyingVol); var contract = new OptionContract(Symbols.SPY_P_192_Feb19_2016, Symbols.SPY) { Time = evaluationDate }; var optionPut = new Option(SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY_P_192_Feb19_2016, Resolution.Minute, tz, tz, true, false, false), new Cash(CashBook.AccountCurrency, 0, 1m), new OptionSymbolProperties(SymbolProperties.GetDefault(CashBook.AccountCurrency))); optionPut.SetMarketPrice(new Tick { Value = price }); optionPut.Underlying = equity; var priceModel = (QLOptionPriceModel)OptionPriceModels.CrankNicolsonFD(); priceModel.EnableGreekApproximation = false; var results = priceModel.Evaluate(optionPut, null, contract); var greeks = results.Greeks; Assert.AreEqual(greeks.Theta, 0); Assert.AreEqual(greeks.Rho, 0); Assert.AreEqual(greeks.Vega, 0); priceModel = (QLOptionPriceModel)OptionPriceModels.CrankNicolsonFD(); priceModel.EnableGreekApproximation = true; results = priceModel.Evaluate(optionPut, null, contract); greeks = results.Greeks; Assert.LessOrEqual(greeks.Theta, 0); Assert.AreNotEqual(greeks.Rho, 0); Assert.Greater(greeks.Vega, 0); }
/// <summary> /// Request Options chain for specific UNL, the request applies for several months ahead! /// </summary> /// <param name="optionToLoadParameters"></param> public async void RequestOptionChain(OptionToLoadParameters optionToLoadParameters) { Logger.Info($"{nameof(RequestOptionChain)} was called, loading {optionToLoadParameters}"); //First: Load pivot option OptionContract optionContract = optionToLoadParameters.OptionContractPivotToLoad; var requestId = GenerateRequestId(); var ibContract = optionContract.ToIbContract(); var task = _handler.WaitForContractDetails(requestId); _clientSocket.reqContractDetails(requestId, ibContract); var contractDetailsList = await task; contractDetailsList.Where(c => optionToLoadParameters.IsOptionWithinLoadBoundaries((OptionContract)c.Summary.ToContract()) ).ForEach(RequestMarketData); }
public override void Initialize() { this.SetStartDate(2017, 1, 1); this.SetEndDate(2017, 6, 28); this.SetCash(25000); this.LogCust("PERIOD: 2017"); // ---------------------------------------------------------------------- // Algo params // ---------------------------------------------------------------------- this.MAX_EXPIRY = 30; this._no_K = 2; this.resol = Resolution.Minute; this.tkr = SPY; // ---------------------------------------------------------------------- // add underlying Equity equity = this.AddEquity(this.tkr, this.resol); equity.SetDataNormalizationMode(DataNormalizationMode.Raw); this.equity_symbol = equity.Symbol; // Add options var option = this.AddOption(this.tkr, this.resol); this.option_symbol = option.Symbol; // set our strike/expiry filter for this option chain option.SetFilter(this.UniverseFunc); // for greeks and pricer (needs some warmup) - https://github.com/QuantConnect/Lean/blob/21cd972e99f70f007ce689bdaeeafe3cb4ea9c77/Common/Securities/Option/OptionPriceModels.cs#L81 option.PriceModel = OptionPriceModels.CrankNicolsonFD(); // this is needed for Greeks calcs this.SetWarmUp(TimeSpan.FromDays(3)); this.call = null; this.put = null; Combo straddle; OrderTickets.Add(new OrderTicketInfo2 { EquityUnderlying = equity }); OrderTickets.Add(new OrderTicketInfo2 { EquityUnderlying = equity }); // ----------------------------------------------------------------------------- // scheduled functions // ----------------------------------------------------------------------------- this.Schedule.On(this.DateRules.EveryDay(this.equity_symbol), this.TimeRules.AfterMarketOpen(this.equity_symbol, 60), new Action(this.CloseOptionsOpen)); this.Schedule.On(this.DateRules.EveryDay(this.equity_symbol), this.TimeRules.BeforeMarketClose(this.equity_symbol, 10), new Action(this.closeOptionsClose)); }
public void BaroneAdesiWhaleyPortfolioTest() { const decimal price = 30.00m; const decimal underlyingPrice = 200m; const decimal underlyingVol = 0.25m; const decimal riskFreeRate = 0.01m; var tz = TimeZones.NewYork; var evaluationDate = new DateTime(2015, 2, 19); var equity = new Equity(SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency)); equity.SetMarketPrice(new Tick { Value = underlyingPrice }); equity.VolatilityModel = new DummyVolatilityModel(underlyingVol); var contract = new OptionContract(Symbols.SPY_C_192_Feb19_2016, Symbols.SPY) { Time = evaluationDate }; var optionCall = new Option(SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY_C_192_Feb19_2016, Resolution.Minute, tz, tz, true, false, false), new Cash(CashBook.AccountCurrency, 0, 1m), new OptionSymbolProperties(SymbolProperties.GetDefault(CashBook.AccountCurrency))); optionCall.SetMarketPrice(new Tick { Value = price }); optionCall.Underlying = equity; var priceModel = OptionPriceModels.BaroneAdesiWhaley(); var results = priceModel.Evaluate(optionCall, null, contract); var callPrice = results.TheoreticalPrice; var impliedVolatility = results.ImpliedVolatility; var greeks = results.Greeks; Assert.Greater(price, callPrice); Assert.Greater(impliedVolatility, underlyingVol); // BS equation (inequality) var rightPart = greeks.Theta + riskFreeRate * underlyingPrice * greeks.Delta + 0.5m * underlyingVol * underlyingVol * underlyingPrice * underlyingPrice * greeks.Gamma; var leftPart = riskFreeRate * callPrice; Assert.GreaterOrEqual(Math.Round(leftPart, 4), Math.Round(rightPart, 4)); }
// // Get ATM call and put // public virtual void get_contracts(Slice slice) { foreach (var kvp in slice.OptionChains) { if (kvp.Key != this.option_symbol) { continue; } var chain = kvp.Value; var spot_price = chain.Underlying.Price; // self.Log("spot_price {}" .format(spot_price)) // prefer to do in steps, rather than a nested sorted // 1. get furthest expiry var contracts_by_T = chain.OrderByDescending(x => x.Expiry).ToList(); if (!(contracts_by_T.Count > 0)) { return; } this.expiry = contracts_by_T[0].Expiry.Date; //this.last_trading_day = last_trading_day(this.expiry); this.last_trading_day = this.expiry; // get contracts with further expiry and sort them by strike var slice_T = (from i in chain where i.Expiry.Date == this.expiry select i).ToList(); var sorted_contracts = slice_T.OrderBy(x => x.Strike).ToList(); // self.Log("Expiry used: {} and shortest {}" .format(self.expiry, contracts_by_T[-1].Expiry.date()) ) // 2a. get the ATM closest CALL to short var calls = (from i in sorted_contracts where i.Right == OptionRight.Call && i.Strike >= spot_price select i).ToList(); //this.call = calls ? calls[0] : null; this.call = calls.Count > 0 ? calls.First() : null; // self.Log("delta call {}, self.call type {}" .format(self.call.Greeks.Delta, type(self.call))) // self.Log("implied vol {} " .format(self.call.ImpliedVolatility)) // 2b. get the ATM closest put to short var puts = (from i in sorted_contracts where i.Right == OptionRight.Put && i.Strike <= spot_price select i).ToList(); this.put = puts.Count > 0 ? puts.Last() : null; } }
// Liquidate opts (with some value) and underlying // public void close_optionsClose() { // check this is the last trading day if (this.last_trading_day != this.Time.Date) { //return; } this.LogCust("On last trading day: liquidate options with value and underlying "); // liquidate options (if invested and in the money [otherwise their price is min of $0.01) Liquid(); this.call = null; this.put = null; OrderTickets.Clear(); OrderTickets.Add(new OrderTicketInfo { EquityUnderlying = equity }); OrderTickets.Add(new OrderTicketInfo { EquityUnderlying = equity }); }
// // Get ATM call and put // public virtual void GetContracts(Slice slice) { LogCust("called get contracts"); foreach (var kvp in slice.OptionChains) { if (kvp.Key != this.option_symbol) { continue; } var chain = kvp.Value; var spot_price = chain.Underlying.Price; // prefer to do in steps, rather than a nested sorted // 1. get furthest expiry var contracts_by_T = chain.OrderByDescending(x => x.Expiry).ToList(); if (!(contracts_by_T.Count > 0)) { return; } this.expiry = contracts_by_T[0].Expiry.Date; // get contracts with further expiry and sort them by strike var slice_T = (from i in chain where i.Expiry.Date == this.expiry select i).ToList(); var sorted_contracts = slice_T.OrderBy(x => x.Strike).ToList(); // 2a. get the ATM closest CALL to short var calls = (from i in sorted_contracts where i.Right == OptionRight.Call && i.Strike >= spot_price select i).ToList(); this.call = calls.Count > 0 ? calls.First() : null; // 2b. get the ATM closest put to short var puts = (from i in sorted_contracts where i.Right == OptionRight.Put && i.Strike <= spot_price select i).ToList(); this.put = puts.Count > 0 ? puts.Last() : null; } }
public void EvaluationDateWorksInPortfolioTest() { const decimal price = 30.00m; const decimal underlyingPrice = 200m; const decimal underlyingVol = 0.25m; const decimal riskFreeRate = 0.01m; var tz = TimeZones.NewYork; var evaluationDate1 = new DateTime(2015, 2, 19); var evaluationDate2 = new DateTime(2015, 2, 20); var equity = new Equity(SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, tz, tz, true, false, false), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency)); equity.SetMarketPrice(new Tick { Value = underlyingPrice }); equity.VolatilityModel = new DummyVolatilityModel(underlyingVol); var contract = new OptionContract(Symbols.SPY_C_192_Feb19_2016, Symbols.SPY) { Time = evaluationDate1 }; var optionCall = new Option(SecurityExchangeHours.AlwaysOpen(tz), new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY_C_192_Feb19_2016, Resolution.Minute, tz, tz, true, false, false), new Cash(CashBook.AccountCurrency, 0, 1m), new OptionSymbolProperties(SymbolProperties.GetDefault(CashBook.AccountCurrency))); optionCall.SetMarketPrice(new Tick { Value = price }); optionCall.Underlying = equity; var priceModel = OptionPriceModels.BaroneAdesiWhaley(); var results = priceModel.Evaluate(optionCall, null, contract); var callPrice1 = results.TheoreticalPrice; contract.Time = evaluationDate2; results = priceModel.Evaluate(optionCall, null, contract); var callPrice2 = results.TheoreticalPrice; Assert.Greater(callPrice1, callPrice2); }
private List <TradableOption> GetTradableOptions(OptionChains chains) { List <TradableOption> res = new List <TradableOption>(); chains.Values.ToList().ForEach((chain) => { //var contracts = chain.Contracts.Values.Where((x) => //{ // return // x.BidPrice > M & // x.BidPrice > 0 & // x.ImpliedVolatility < MAX_IV & // x.Expiry >= Time.AddDays(MIN_EXPIRATION_DAYS) & // x.Expiry <= Time.AddDays(MAX_EXPIRATION_DAYS); //}); var contracts = chain.Contracts.Values; var calls = contracts.Where((x) => x.Right == OptionRight.Call); var puts = contracts.Where((x) => x.Right == OptionRight.Put); // get symbol IV out of the closest put&call avarage IV. OptionContract closestCall = calls.MinBy((x) => Math.Abs(chain.Underlying.Price - x.Strike)).FirstOrDefault(); OptionContract closestPut = puts.MinBy((x) => Math.Abs(chain.Underlying.Price - x.Strike)).FirstOrDefault(); decimal IV = closestCall != null & closestPut != null ? (closestCall.ImpliedVolatility + closestPut.ImpliedVolatility) / 2 : 0; OptionContract bestCall = calls.Where((x) => (x.BidPrice + x.Strike) > chain.Underlying.Price * P && x.BidPrice > M).OrderByDescending((x) => x.Expiry).FirstOrDefault(); OptionContract bestPut = puts.Where((x) => (x.Strike - x.BidPrice) < chain.Underlying.Price * (2 - P) && x.BidPrice > M).OrderByDescending((x) => x.Expiry).FirstOrDefault(); res.Add(new TradableOption() { Symbol = chain.Symbol, Call = bestCall, Put = bestPut, IV = IV }); }); return(res); }
public void BaroneAdesiWhaleyPortfolioTest() { const decimal price = 30.00m; const decimal underlyingPrice = 200m; const decimal underlyingVol = 0.25m; const decimal riskFreeRate = 0.01m; var tz = TimeZones.NewYork; var spy = Symbols.SPY; var evaluationDate = new DateTime(2015, 2, 19); var SPY_C_192_Feb19_2016E = GetOptionSymbol(spy, OptionStyle.American, OptionRight.Call); var equity = GetEquity(spy, underlyingPrice, underlyingVol, tz); var contract = new OptionContract(Symbols.SPY_C_192_Feb19_2016, Symbols.SPY) { Time = evaluationDate }; var optionCall = GetOption(SPY_C_192_Feb19_2016E, equity, tz); optionCall.SetMarketPrice(new Tick { Value = price }); var priceModel = OptionPriceModels.BaroneAdesiWhaley(); var results = priceModel.Evaluate(optionCall, null, contract); var callPrice = results.TheoreticalPrice; var impliedVolatility = results.ImpliedVolatility; var greeks = results.Greeks; Assert.Greater(price, callPrice); Assert.Greater(impliedVolatility, underlyingVol); // BS equation (inequality) var rightPart = greeks.Theta + riskFreeRate * underlyingPrice * greeks.Delta + 0.5m * underlyingVol * underlyingVol * underlyingPrice * underlyingPrice * greeks.Gamma; var leftPart = riskFreeRate * callPrice; Assert.GreaterOrEqual(Math.Round(leftPart, 4), Math.Round(rightPart, 4)); }
public void AddOption(object obj) { bool correctOption; typeWarningLabel.Visibility = Visibility.Hidden; priceWarningLabel.Visibility = Visibility.Hidden; dateWarningLabel.Visibility = Visibility.Hidden; existWarningLabel.Visibility = Visibility.Hidden; correctOption = CheckButtons(); correctOption = CheckPrice() && correctOption; correctOption = CheckDate() && correctOption; if (correctOption) { OptionContract.Type optionType; if (PutButton) { optionType = OptionContract.Type.Put; } else { optionType = OptionContract.Type.Call; } double Strike = Convert.ToDouble(priceTextbox); DateTime Maturity = (DateTime)maturityDate; OptionContract optionContract = new OptionContract(optionType, 1, Strike, Maturity); if (CheckExist(optionContract)) { dataReceiver.AddOptionToPricer(optionContract); } this.Close(obj); } }
public override void OnData(Slice slice) { OptionChain chain; if (!Portfolio.Invested && IsMarketOpen(OptionSymbol)) { if (slice.OptionChains.TryGetValue(OptionSymbol, out chain)) { _optionContract = chain.FirstOrDefault(c => c.Expiry.Date == new DateTime(2014, 04, 19) && c.OpenInterest > 0); if (_optionContract != null) { MarketOrder(_optionContract.Symbol, 1); } } } Delisting delisting; if (slice.Delistings.TryGetValue(_optionContract.Symbol, out delisting)) { Log(delisting.ToString()); _delistings.Add(delisting); } }
/// <summary> /// Check if the option is between the striks boundary. /// /// </summary> /// <param name="optionContract"></param> /// <returns></returns> public bool IsOptionWithinLoadBoundaries(OptionContract optionContract) { //Get only Monthly option chain, not weekly!, Every monthly expires at the 3'd friday of the month/ if (optionContract.Expiry.Equals(optionContract.Expiry.GetThirdFridayOfMonth()) == false) { return(false); } //Check expiration boundaries: if (DateTime.Now.AddDays(MinDaysToExpiration) > optionContract.Expiry) { return(false); } if (optionContract.Expiry > DateTime.Now.AddDays(MaxDaysToExpiration)) { return(false); } //Check strike boundaries: if ((optionContract.Strike > MaxStrike) || (optionContract.Strike < MinStrike)) { return(false); } return(true); }