Пример #1
0
        private InstrumentParams GetUpdatedInstrumentParams(int isinId)
        {
            InstrumentParams ip = null;

            using (containerLock.UpgradableReadLock())
            {
                if (!mapIsinId2InstrumentParams.TryGetValue(isinId, out ip))
                {
                    using (containerLock.WriteLock())
                    {
                        var code = instrumentResolver.GetShortIsinByIsinId(isinId);
                        if (!string.IsNullOrEmpty(code))
                        {
                            var data = instrumentResolver.GetInstrument(code);
                            if (!data.Equals(default(InstrumentData)))
                            {
                                ip = new InstrumentParams
                                {
                                    Instrument           = data.Instrument,
                                    VolaTranslatedByFeed = true,
                                    SessionEndTime       = sessionEndTime
                                };
                            }
                        }

                        if (ip != null)
                        {
                            mapIsinId2InstrumentParams.Add(isinId, ip);
                        }
                    }
                }
            }

            return(ip);
        }
Пример #2
0
        public static uint GetDecimalPlaces(this InstrumentParams ip)
        {
            if (ip.DecimalPlaces > 0)
            {
                return(ip.DecimalPlaces);
            }

            if (ip.PriceStep <= 0)
            {
                return(4);
            }

            return(decimalPlaces.GetOrAdd(ip.Instrument, _ =>
            {
                uint precision = 0;
                var x = ip.PriceStep;

                while (x * (decimal)Math.Pow(10, precision) != Math.Round(x * (decimal)Math.Pow(10, precision)))
                {
                    precision++;
                }

                return precision;
            }));
        }
        public async Task <IActionResult> GetInstrumentsPaged([FromQuery] InstrumentParams instrumentParams)
        {
            var items = await _repo.GetInstrumentsPaged(instrumentParams);

            var itemsDto = _mapper.Map <List <DtoInstrument> >(items);

            Response.AddPagination(items.CurrentPage, items.PageSize, items.TotalCount, items.TotalPages);
            return(Ok(itemsDto));
        }
Пример #4
0
 public InstrumentSubscription(Instrument instrument, IQFeedInstrumentData data, Action <InstrumentSubscription> onTimeout)
 {
     Instrument       = instrument;
     InstrumentParams = new InstrumentParams {
         Instrument = instrument
     };
     Code           = data.Symbol;
     SecurityType   = data.SecurityType;
     this.onTimeout = onTimeout;
 }
Пример #5
0
        private async Task HandleAsync(QLInstrumentParams message)
        {
            var instrument = await adapter.ResolveInstrumentAsync(message.code);

            if (instrument == null)
            {
                Logger.Error().Print($"Unable to resolve instrument for {message.code}");
                return;
            }

            decimal pricemin = 0, pricemax = 0;

            decimal.TryParse(message.pricemin, out pricemin);
            decimal.TryParse(message.pricemax, out pricemax);

            // цены шага
            var stepPrices = new[]
            { message.stepPriceT, message.stepPrice, message.stepPriceCl, message.stepPricePrCl };

            // первая ненулевая цена шага
            var stepPriceValue = stepPrices.FirstOrDefault(x => x != 0);

            // проверить утверждение: любая цена шага равна либо stepPriceValue, либо 0
            //Debug.Assert(stepPrices.All(x => x == stepPriceValue || x == 0));
            // NOTE выяснилось, что утверждение иногда не выполняется. Замечен случай с BRM6 stepPricePrCl=stepPrice=stepPriceT=6.61737, stepPriceCl=6.63015

            var ip = new InstrumentParams
            {
                Instrument           = instrument,
                BestBidPrice         = message.bid,
                LastPrice            = message.last,
                LotSize              = message.lotsize,
                BestOfferPrice       = message.offer,
                Vola                 = message.volatility,
                BestBidQuantity      = message.bidQuantity,
                BestOfferQuantity    = message.offerQuantity,
                PriceStep            = message.priceStep,
                PriceStepValue       = stepPriceValue,
                Settlement           = message.settlement,
                PreviousSettlement   = message.previousSettlement,
                BottomPriceLimit     = pricemin,
                TopPriceLimit        = pricemax,
                VolaTranslatedByFeed = true,
                SessionEndTime       = message.endTime,
                OpenInterest         = message.openinterest
            };

            OnMessageReceived(ip);

            using (fullCodesLock.Lock())
            {
                fullCodes[ip.Instrument] = message.fullCode;
            }
        }
Пример #6
0
        private InstrumentParams GetInstrumentParams(Instrument instrument)
        {
            if (!paramDictionary.TryGetValue(instrument, out var ip))
            {
                paramDictionary[instrument] = ip = new InstrumentParams
                {
                    Instrument = instrument,
                };
            }

            return(ip);
        }
        public InstrumentParams GetInstrumentParams(Instrument instrument)
        {
            using (syncRoot.Lock())
            {
                InstrumentParams instrumentParams;
                if (!cachedInstrumentParams.TryGetValue(instrument, out instrumentParams))
                {
                    instrumentParams = new InstrumentParams {
                        Instrument = instrument
                    };
                    cachedInstrumentParams.Add(instrument, instrumentParams);
                }

                return(instrumentParams);
            }
        }
Пример #8
0
            public InstrumentSubscription(
                CQGCInstrumentResolver instrumentResolver,
                Instrument instrument,
                uint contractId)
            {
                this.instrumentResolver = instrumentResolver;
                Instrument = instrument;
                lockCookie = DeadlockMonitor.Cookie <InstrumentSubscription>("lockCookie-" + ContractId);
                ContractId = contractId;

                InstrumentParams = new InstrumentParams {
                    Instrument = instrument
                };
                InstrumentParams.VolaTranslatedByFeed = false;
                OrderBook = new OrderBook();
            }
Пример #9
0
        public async Task <SubscriptionResult> Subscribe(Instrument instrument)
        {
            var code = await connector.ResolveInstrumentAsync(instrument);

            if (code == null)
            {
                return(SubscriptionResult.Error(instrument, "Unable to resolve instrument symbol"));
            }

            using (allInstrumentLock.WriteLock())
            {
                if (allInstruments.Contains(code))
                {
                    if (!subscribedInstruments.Contains(code))
                    {
                        subscribedInstruments.Add(code);

                        InstrumentParams ip;
                        if (instrumentsParams.TryGetValue(code, out ip))
                        {
                            OnMessageReceived(ip);
                        }
                        else
                        {
                            ip = new InstrumentParams {
                                Instrument = instrument
                            };
                            instrumentsParams[code] = ip;
                        }

                        return(SubscriptionResult.OK(instrument));
                    }

                    return(SubscriptionResult.Error(instrument, "Already subscribed."));
                }
            }

            return(SubscriptionResult.Error(instrument, "Instrument doesn't exist."));
        }
Пример #10
0
            public SendMessageFlags Handle(ContractMetadata metadata)
            {
                var result = SendMessageFlags.None;

                var tickSize = (decimal)metadata.tick_size;

                if (InstrumentParams.PriceStep != tickSize)
                {
                    InstrumentParams.PriceStep = tickSize;
                    result |= SendMessageFlags.InstrumentParams;
                }

                var tickValue = (decimal)metadata.tick_value;

                if (InstrumentParams.PriceStepValue != tickValue)
                {
                    InstrumentParams.PriceStepValue = tickValue;
                    result |= SendMessageFlags.InstrumentParams;
                }

                // ситуация, когда шаг цены инструмента - плавающая
                if (metadata.tick_sizes_by_price != null && metadata.tick_sizes_by_price.Count > 0)
                {
                    TickSizesByPrice = metadata.tick_sizes_by_price.OrderBy(_ => _.minimum_price).ToList();
                }

                var decimalPlaces = metadata.display_price_scale <= 15 // См. описание поля display_price_scale в WebAPI.proto
                        ? metadata.display_price_scale
                        : InstrumentParams.GetDecimalPlaces();         // DecimalPlaces считаются по PriceStep

                if (InstrumentParams.DecimalPlaces != decimalPlaces)
                {
                    InstrumentParams.DecimalPlaces = decimalPlaces;
                    result |= SendMessageFlags.InstrumentParams;
                }

                return(result);
            }
Пример #11
0
        public async Task <PagedList <Instrument> > GetInstrumentsPaged(InstrumentParams instrumentParams)
        {
            var items = _context.Instruments.OrderBy(x => x.Name).AsQueryable();

            return(await PagedList <Instrument> .CreateAsync(items, instrumentParams.PageNumber, instrumentParams.PageSize));
        }
        /// <summary>
        /// Расчёт расширенных (теоретических) параметров опциона.
        /// </summary> 
        /// <param name="ip">
        /// Параметры инструмента (опциона).
        /// </param>
        /// <param name="oep">
        /// Параметры расчета опциона.
        /// </param>
        InstrumentCalculatedParams IModel.CalcPriceAndGreeks(InstrumentParams ip, OptionEvaluationParams oep)
        {
            // Создаём шаблон результата
            var rValue = new InstrumentCalculatedParams(ip);

            // Проверяем переданные параметры расчёта опциона.
            if (!PopulateOptionEvaluationParams(ip, ref oep))
                return rValue; // Расчёт по переданным параметрам невозможен.

            Debug.Assert(oep.BaseActivePrice != null, "oep.BaseActivePrice != null");
            Debug.Assert(oep.Time != null, "oep.Time != null");
            Debug.Assert(oep.Vola != null, "oep.Vola != null");
            Debug.Assert(oep.VolaShift != null, "oep.VolaShift != null");

            // Рассчитываем количество лет до экспирации опциона.
            var T = GetYearsTillExpiration(ip, oep.Time.Value);

            // Сохраняем цену базового актива для которой выполняется расчёт
            rValue.BaseAssetPrice = oep.BaseActivePrice.Value;
            // Сохраняем волатильность для которой выполняется расчёт
            rValue.TheorIV = oep.Vola.Value + oep.VolaShift.Value;
            // Сохраняем дату и время для которых выполняется расчёт
            // Этого свойства пока нет в публичной версии (будет в 12.8)
            //rValue.Time = oep.Time;

            // Считаем цену и греки через модель Black-Scholes
            var all = BlackScholes.CalcPriceAndGreeks(ip.OptionType,
                                                      oep.BaseActivePrice.Value,
                                                      (double)ip.Strike,
                                                      T,
                                                      0, // TODO Добавить ставку в OptionEvaluationParams
                                                      oep.Vola.Value + oep.VolaShift.Value);

            // Сохраняем цену и греки
            rValue.TheorPrice = all[0];
            rValue.Delta = all[1];
            rValue.Gamma = all[2];
            rValue.Vega = all[3];
            rValue.Theta = all[4];

            return rValue;
        }
 private static double GetYearsTillExpiration(InstrumentParams ip, DateTime dateTime)
 {
     // HARDCODE: Время окончания сессии (экспирации опционов) на FORTS
     return BlackScholes.YearsBetweenDates(dateTime, ip.ExpirationDate.Date.AddHours(18).AddMinutes(45));
 }
Пример #14
0
 /// <summary>
 ///     Выплюнуть из фида параметры инструмента
 /// </summary>
 /// <param name="instrumentParams">
 ///     Параметры инструмента
 /// </param>
 internal void Transmit(InstrumentParams instrumentParams) => OnMessageReceived(instrumentParams);
        /// <summary>
        /// Проверка и заполнение параметров расчёта опциона.
        /// </summary>
        /// <param name="ip">Параметры инструмента (опциона).</param>
        /// <param name="oep">Парамметры расчёта опциона.</param>
        /// <returns>true если параметры валидны, false если расчёт по данным параметрам невозможен.</returns>
        private bool PopulateOptionEvaluationParams(InstrumentParams ip, ref OptionEvaluationParams oep)
        {
            #region Цена базового актива

            // Если не указана конкретная цена базового актива по которой нужно выполнять расчёт
            if (!oep.BaseActivePrice.HasValue)
            {
                // Пытаемся получить параметры фьючерса для данного опциона
                var ba = InstrumentParamsProvider.GetOptionFuturesParams(ip.Instrument);

                if (ba == null) // Если параметры фьючерса не получены - мы не можем выполнить расчёт
                    return false;

                oep.BaseActivePrice = ba.GetLastPriceOrSettlement(); // Получаем последнюю цену фьючерса
            }

            #endregion

            #region Время

            if (!oep.Time.HasValue)
            {
                // Если не указана точка во времени для которой нужно рассчитать цену опциона выполняем расчёт для текущего времени
                oep.Time = DateTime.Now;
            }

            #endregion

            #region Волатильность

            // Если не указана волатильность для которой нужно выполнять расчёт
            if (!oep.Vola.HasValue)
            {
                oep.Vola = (double)GetVola(ip); // Запрашиваем волатильность от этой же модели
            }

            #endregion

            #region Сдвиг волатильности

            // Если не задан сдвиг волатильности для которого нужно выполнять расчёт
            if (!oep.VolaShift.HasValue)
            {
                oep.VolaShift = 0;
            }

            #endregion

            return true; // Все параметры заполнены, можно производить расчёт
        }
 /// <summary>
 /// Получение волатильности используемой в модели для опциона.
 /// </summary>
 /// <param name="ip">Параметры инструмента.</param>
 /// <returns>Волатильность.</returns>
 public decimal GetVola(InstrumentParams ip)
 {
     return ip.Volty + modelVolaShift; // Берём сдвиг волатильности заданный через контрол настройки
 }
        /// <summary>
        /// Расчёт цены опциона.
        /// </summary> 
        /// <param name="ip">
        /// Параметры инструмента (опциона).
        /// </param>
        /// <param name="oep">
        /// Параметры расчета опциона.
        /// </param>
        public double CalcPrice(InstrumentParams ip, OptionEvaluationParams oep)
        {
            // Проверяем переданные параметры расчёта опциона.
            if (!PopulateOptionEvaluationParams(ip, ref oep))
                return 0; // Расчёт по переданным параметрам невозможен.

            Debug.Assert(oep.BaseActivePrice != null, "oep.BaseActivePrice != null");
            Debug.Assert(oep.Time != null, "oep.Time != null");
            Debug.Assert(oep.Vola != null, "oep.Vola != null");
            Debug.Assert(oep.VolaShift != null, "oep.VolaShift != null");

            // Рассчитываем количество лет до экспирации опциона.
            var T = GetYearsTillExpiration(ip, oep.Time.Value);

            // Считаем цену опциона через модель Black-Scholes
            return BlackScholes.Price(ip.OptionType,
                                      oep.BaseActivePrice.Value,
                                      (double)ip.Strike,
                                      T,
                                      0, // TODO Добавить ставку в OptionEvaluationParams
                                      oep.Vola.Value + oep.VolaShift.Value);
        }
 /// <summary>
 ///     Конструктор
 /// </summary>
 /// <param name="instrument">
 ///     Инструмент
 /// </param>
 /// <param name="instrumentParams">
 ///     Параметры инструмента
 /// </param>
 public InstrumentParamsEventArgs([NotNull] Instrument instrument, [NotNull] InstrumentParams instrumentParams)
 {
     Instrument       = instrument;
     InstrumentParams = instrumentParams;
 }