コード例 #1
0
        /// <summary>
        /// Populates CallPriceMarketData data structure from options
        /// quotes and additional calls to market data.
        /// </summary>
        /// <param name="provider">The underlying market data provider.</param>
        /// <param name="mdq">The underlying query.</param>
        /// <param name="quotes">The options quotes list.</param>
        /// <param name="data">The data structure to be populated.</param>
        /// <returns>The status of the operation.</returns>
        public static RefreshStatus GetCallPriceMarketData(IMarketDataProvider provider, MarketDataQuery mdq, List <IOptionQuote> quotes, Fairmat.MarketData.CallPriceMarketData data)
        {
            // Gets call options.
            var calls = quotes.FindAll(x => x.Type == OptionQuoteType.Call);
            var puts  = quotes.FindAll(x => x.Type == OptionQuoteType.Put);

            // Get maturities and strikes.
            var maturtiesDates = quotes.Select(item => item.Maturity).Distinct().OrderBy(x => x).ToList();
            var strikes        = quotes.Select(item => item.Strike).Distinct().OrderBy(x => x).ToList();

            data.Strike = (Vector)strikes.ToArray();
            //var callMaturtiesDates = calls.Select(item => item.MaturityDate).Distinct().ToList();

            Console.WriteLine("Maturities");
            data.Maturity = new Vector(maturtiesDates.Count);
            for (int z = 0; z < maturtiesDates.Count; z++)
            {
                data.Maturity[z] = RightValueDate.DatesDifferenceCalculator(mdq.Date, maturtiesDates[z]);
            }

            data.CallPrice = new Matrix(data.Maturity.Length, data.Strike.Length);
            var putPrices = new Matrix(data.Maturity.Length, data.Strike.Length);

            // Group maturities, calls, puts  with respect to strikes.
            Dictionary <double, Tuple <List <double>, List <double>, List <double> > > atm = new Dictionary <double, Tuple <List <double>, List <double>, List <double> > >();

            for (int si = 0; si < data.Strike.Length; si++)
            {
                for (int mi = 0; mi < maturtiesDates.Count; mi++)
                {
                    IOptionQuote callQuote = calls.Find(x => x.Strike == data.Strike[si] && x.Maturity == maturtiesDates[mi]);
                    if (callQuote != null)
                    {
                        data.CallPrice[mi, si] = callQuote.Price;
                    }

                    IOptionQuote putQuote = puts.Find(x => x.Strike == data.Strike[si] && x.Maturity == maturtiesDates[mi]);
                    if (putQuote != null)
                    {
                        putPrices[mi, si] = putQuote.Price;
                    }

                    if (callQuote != null && putQuote != null)
                    {
                        Tuple <List <double>, List <double>, List <double> > element = null;

                        if (atm.ContainsKey(data.Strike[si]))
                        {
                            element = atm[data.Strike[si]];
                        }
                        else
                        {
                            element = new Tuple <List <double>, List <double>, List <double> >(new List <double>(), new List <double>(), new List <double>());
                            atm.Add(data.Strike[si], element);
                        }

                        element.Item1.Add(data.Maturity[mi]);
                        element.Item2.Add(callQuote.Price);
                        element.Item3.Add(putQuote.Price);
                    }
                }
            }

            Console.WriteLine("CallPrices");
            Console.WriteLine(data.CallPrice);
            Console.WriteLine("Putprices");
            Console.WriteLine(putPrices);

            // Request the spot price .
            var mdq2 = DVPLI.ObjectSerialization.CloneObject(mdq) as MarketDataQuery;

            mdq2.MarketDataType = typeof(Scalar).ToString();
            IMarketData s0;
            var         s0Result = provider.GetMarketData(mdq2, out s0);

            if (s0Result.HasErrors)
            {
                return(s0Result);
            }

            data.S0 = (s0 as Scalar).Value;

            // Load atm info (get the strike with the higher number of elements).
            int    maxElements = -1;
            double argMax      = -1;

            // Keeps the Strike-Spot distance.
            double spotDistance = double.MaxValue;

            // Find the options which minimize the distance from strike price and spot price.
            foreach (double strike in atm.Keys)
            {
                double distance = Math.Abs(strike - data.S0);
                if (distance < spotDistance)
                {
                    spotDistance = distance;
                    maxElements  = atm[strike].Item1.Count;
                    argMax       = strike;
                }
            }

            if (spotDistance != double.MaxValue)
            {
                data.StrikeATM    = argMax;
                data.MaturityATM  = (Vector)atm[argMax].Item1.ToArray();
                data.CallPriceATM = (Vector)atm[argMax].Item2.ToArray();
                data.PutPriceATM  = (Vector)atm[argMax].Item3.ToArray();
            }
            else
            {
                Console.WriteLine("Cannot find atm information");
            }

            data.Ticker = mdq.Ticker;
            data.Market = mdq.Market;
            data.Date   = mdq.Date;

            return(new RefreshStatus());
        }