示例#1
0
 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;
         }
     }
 }
示例#2
0
        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);
        }
示例#3
0
        /// <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}";
        }
示例#4
0
        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);
        }
示例#5
0
 private static void UpdateContract(OptionContract contract, TradeBar tradeBar)
 {
     if (tradeBar.Close == 0m)
     {
         return;
     }
     contract.LastPrice = tradeBar.Close;
     contract.Volume    = (long)tradeBar.Volume;
 }
示例#6
0
        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");
            }
        }
示例#8
0
 public Market Market(OptionContract instrument)
 {
     if (this._markets.ContainsKey(instrument.ID))
     {
         return(this._markets[instrument.ID]);
     }
     else
     {
         return(null);
     }
 }
示例#9
0
 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;
     }
 }
示例#10
0
        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));
        }
示例#12
0
        /// <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);
        }
示例#13
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);
 }
示例#16
0
        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);
            }
        }
示例#17
0
        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);
            }
        }
示例#18
0
        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);
        }
示例#19
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));
        }
示例#21
0
        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));
        }
示例#22
0
 //
 //         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;
            }
        }
示例#25
0
        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);
        }
示例#26
0
        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);
        }
示例#27
0
        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));
        }
示例#28
0
        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);
            }
        }
示例#30
0
        /// <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);
        }