예제 #1
0
        /// <summary>
        /// Get options chain
        /// </summary>
        /// <param name="inputs"></param>
        /// <returns></returns>
        public override async Task <IList <IInstrumentOptionModel> > GetOptionChains(IDictionary <dynamic, dynamic> inputs)
        {
            var options  = new List <IInstrumentOptionModel>();
            var response = await GetResponse <InputOptionChainDataModel>($"/v1/markets/options/chains", inputs);

            foreach (var inputOption in response?.Chains?.Chain ?? new List <InputOptionModel>())
            {
                var pointModel = new PointModel
                {
                    Bid     = inputOption.Bid,
                    Ask     = inputOption.Ask,
                    Price   = inputOption.Last,
                    BidSize = inputOption.BidSize,
                    AskSize = inputOption.AskSize
                };

                var optionModel = new InstrumentOptionModel
                {
                    Point          = pointModel,
                    Strike         = inputOption.Strike,
                    Volume         = inputOption.Volume,
                    AverageVolume  = inputOption.AverageVolume,
                    ContractSize   = inputOption.ContractSize,
                    OpenInterest   = inputOption.OpenInterest,
                    ExpirationDate = inputOption.ExpirationDate,
                    Side           = OptionTypeMap.Input(inputOption.OptionType),
                    Variance       = new InstrumentOptionVarianceModel
                    {
                        Vega         = inputOption.Greeks.Vega,
                        Delta        = inputOption.Greeks.Delta,
                        Gamma        = inputOption.Greeks.Gamma,
                        Theta        = inputOption.Greeks.Theta,
                        Interest     = inputOption.Greeks.Rho,
                        Distribution = inputOption.Greeks.Phi,
                        AskIv        = inputOption.Greeks.AskIv,
                        BidIv        = inputOption.Greeks.BidIv,
                        Iv           = inputOption.Greeks.Iv
                    }
                };

                options.Add(optionModel);
            }

            return(options);
        }
예제 #2
0
        /// <summary>
        /// Get options chain
        /// </summary>
        /// <param name="inputs"></param>
        /// <returns></returns>
        protected async Task <IList <IInstrumentOptionModel> > GetOptionsChain(dynamic inputs)
        {
            var options  = new List <IInstrumentOptionModel>();
            var response = await GetResponse <InputOptionItemModel>($"/v1/markets/options/chains");

            foreach (var inputOption in response.Options)
            {
                var optionModel = new InstrumentOptionModel
                {
                    Bid    = inputOption.Bid,
                    Ask    = inputOption.Ask,
                    Price  = inputOption.Last,
                    Strike = inputOption.Strike
                };

                options.Add(optionModel);
            }

            return(options);
        }
예제 #3
0
        /// <summary>
        /// Data updates
        /// </summary>
        private async Task OnData()
        {
            // Get price

            var instrument = (await DataService
                              .GetInstruments(Chains.Select(o => o.Symbol).ToList()))
                             .FirstOrDefault()
                             .Value;

            if (instrument == null)
            {
                return;
            }

            // Get chains

            var optionQueries = Chains.Select(chain =>
            {
                var inputs = new Dictionary <dynamic, dynamic>
                {
                    ["greeks"]     = Variance,
                    ["symbol"]     = chain.Symbol,
                    ["expiration"] = chain.Expiration
                };

                return(DataService.GetOptionChain(inputs));
            });

            var options = (await Task
                           .WhenAll(optionQueries))
                          .SelectMany(o => o)
                          .GroupBy(o => o.Strike)
                          .ToDictionary(o => o.Key, o => o.Where(v => Where(v)).ToList())
                          .OrderBy(o => o.Key)
                          .ToList();

            // Find the current strike

            var closeIndex    = -1;
            var closeDistance = double.MaxValue;

            for (var i = 0; i < options.Count; i++)
            {
                var distance = Math.Abs(instrument.Point.Price.Value - options[i].Key.Value);

                if (closeDistance > distance)
                {
                    closeIndex    = i;
                    closeDistance = distance;
                }
            }

            if (closeIndex < 0)
            {
                return;
            }

            // Aggregate around the current strike

            var index        = 0;
            var minSum       = 0.0;
            var maxSum       = 0.0;
            var currentPrice = instrument.Point.Price.Value;
            var summaries    = new InstrumentOptionModel[options.Count];
            var sources      = new Dictionary <string, ISeriesModel>();

            while (true)
            {
                var curMins = options.ElementAtOrDefault(closeIndex - index);
                var curMaxs = options.ElementAtOrDefault(closeIndex + index);

                if (curMins.Value == null && curMaxs.Value == null)
                {
                    break;
                }

                if (curMins.Value != null)
                {
                    minSum += SelectMany(curMins.Value, curMins.Key, currentPrice).Value;
                    summaries[closeIndex - index] = new InstrumentOptionModel
                    {
                        Strike = curMins.Key,
                        Side   = OptionSideEnum.Put,
                        Point  = new Core.ModelSpace.PointModel {
                            Price = minSum
                        }
                    };
                }

                if (curMaxs.Value != null)
                {
                    maxSum += SelectMany(curMaxs.Value, curMaxs.Key, currentPrice).Value;
                    summaries[closeIndex + index] = new InstrumentOptionModel
                    {
                        Strike = curMaxs.Key,
                        Side   = OptionSideEnum.Call,
                        Point  = new Core.ModelSpace.PointModel {
                            Price = maxSum
                        }
                    };
                }

                index++;
            }

            // Create points with values for each expiration

            var points = summaries.Select(o =>
            {
                var strike      = o.Strike;
                var series      = new Dictionary <string, ISeriesModel>();
                var seriesColor = Brushes.Black.Color;
                var seriesName  = "Aggregation";

                switch (o.Side)
                {
                case OptionSideEnum.Put: seriesColor = Brushes.OrangeRed.Color; break;

                case OptionSideEnum.Call: seriesColor = Brushes.LimeGreen.Color; break;
                }

                sources[seriesName] = series[seriesName] = new SeriesModel
                {
                    Name  = seriesName,
                    Shape = new BarSeries(),
                    Model = new ExpandoModel
                    {
                        ["Color"] = seriesColor,
                        ["Point"] = o.Point.Price
                    }
                };

                // Create point with all series

                var point = new Chart.ModelSpace.PointModel()
                {
                    Areas = new Dictionary <string, IAreaModel>
                    {
                        [_name] = new AreaModel
                        {
                            Name   = _name,
                            Series = series
                        }
                    }
                };

                point["Strike"] = strike;

                return(point as Chart.ModelSpace.IPointModel);
            }).ToList();

            // Set appropriate number of series on the chart

            if (sources.Any())
            {
                View.Composer.Group.Series = sources;
            }

            await Dispatcher.BeginInvoke(new Action(() =>
            {
                var composer = View.Composer;

                composer.IndexDomain ??= new int[2];
                composer.IndexDomain[0] = 0;
                composer.IndexDomain[1] = options.Count;
                composer.Items = _points = points.ToList();
                composer.Update();
            }));
        }