예제 #1
0
        internal static void FillNodeInfoDeribit(InteractivePointActive ip,
                                                 double f, double dT, IOptionStrikePair sInfo,
                                                 StrikeType optionType, OptionPxMode optPxMode,
                                                 double optPx, double optQty, double optSigma, DateTime optTime, bool returnPct, double riskfreeRatePct, double scaleMult)
        {
            // Вызов базовой реализации
            FillNodeInfo(ip, f, dT, sInfo, optionType, optPxMode, optPx, optQty, optSigma, optTime, returnPct, riskfreeRatePct);

            // Заменяю тултип, чтобы в нем были и биткойны и доллары
            var opTypeStr   = String.Intern(optionType.ToString());
            var opTypeSpace = String.Intern(new string(' ', opTypeStr.Length));

            // Пробелы по виду занимают меньше места, чем буквы, поэтому чуть-чуть подравниваю?
            opTypeSpace += "  ";
            if (optQty > 0)
            {
                ip.Tooltip = String.Format(CultureInfo.InvariantCulture,
                                           " K:{0}; IV:{1:###0.00}%\r\n" +
                                           " {2} px(B) {3:##0.0000} qty {4}\r\n" +
                                           " {5} px($) {6:######0.00} qty {4}",
                                           sInfo.Strike, optSigma * Constants.PctMult, opTypeStr, optPx, optQty,
                                           opTypeSpace, optPx * scaleMult);
            }
            else
            {
                ip.Tooltip = String.Format(CultureInfo.InvariantCulture,
                                           " K:{0}; IV:{1:###0.00}%\r\n" +
                                           " {2} px(B) {3:##0.0000}\r\n" +
                                           " {4} px($) {5:######0.00}",
                                           sInfo.Strike, optSigma * Constants.PctMult, opTypeStr, optPx,
                                           opTypeSpace, optPx * scaleMult);
            }
        }
        internal static void FillNodeInfo(InteractivePointActive ip,
                                          double f, double dT, IOptionStrikePair sInfo,
                                          StrikeType optionType, OptionPxMode optPxMode,
                                          double optSigma, bool returnPct, bool isVisiblePoints, double scaleMult, double riskfreeRatePct)
        {
            if (optionType == StrikeType.Any)
            {
                throw new ArgumentException("Option type 'Any' is not supported.", "optionType");
            }

            bool   isCall = (optionType == StrikeType.Call);
            double optPx  = FinMath.GetOptionPrice(f, sInfo.Strike, dT, optSigma, 0, isCall);

            // Сразу переводим котировку из баксов в битки
            optPx /= scaleMult;

            // ReSharper disable once UseObjectOrCollectionInitializer
            SmileNodeInfo nodeInfo = new SmileNodeInfo();

            nodeInfo.F            = f;
            nodeInfo.dT           = dT;
            nodeInfo.RiskFreeRate = riskfreeRatePct;
            nodeInfo.Sigma        = returnPct ? optSigma * Constants.PctMult : optSigma;
            nodeInfo.OptPx        = optPx;
            nodeInfo.Strike       = sInfo.Strike;
            // Сюда мы приходим когда хотим торговать, поэтому обращение к Security уместно
            nodeInfo.Security   = (optionType == StrikeType.Put) ? sInfo.Put.Security : sInfo.Call.Security;
            nodeInfo.PxMode     = optPxMode;
            nodeInfo.OptionType = optionType;
            nodeInfo.Pair       = sInfo;
            //nodeInfo.ScriptTime = optTime;
            nodeInfo.CalendarTime = DateTime.Now;

            nodeInfo.Symbol   = nodeInfo.Security.Symbol;
            nodeInfo.DSName   = nodeInfo.Security.SecurityDescription.DSName;
            nodeInfo.Expired  = nodeInfo.Security.SecurityDescription.Expired;
            nodeInfo.FullName = nodeInfo.Security.SecurityDescription.FullName;

            ip.Tag = nodeInfo;
            //ip.Color = Colors.Yellow;
            ip.IsActive     = isVisiblePoints;
            ip.Geometry     = Geometries.Ellipse;
            ip.DragableMode = DragableMode.None;
            //ip.Value = new System.Windows.Point(sInfo.Strike, nodeInfo.Sigma);
            // Поскольку цены скорее всего расчетные, показываю на 1 знак болььше, чем объявлена точность в инструменте
            int    decim    = Math.Max(0, nodeInfo.Security.Decimals + 1);
            string optPxStr = optPx.ToString("N" + decim, CultureInfo.InvariantCulture);

            ip.Tooltip = String.Format(CultureInfo.InvariantCulture,
                                       " K: {0}; IV: {1:#0.00}%\r\n   {2} px {3}",
                                       sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx);
        }
예제 #3
0
        private void InteractiveSplineOnClickEvent(object sender, InteractiveActionEventArgs eventArgs)
        {
            OptionPxMode pxMode = m_isLong ? OptionPxMode.Ask : OptionPxMode.Bid;

            PositionsManager posMan = PositionsManager.GetManager(m_context);
            // Из практики торговли часто бывает ситуация, что торговля заблокирована, а снять задачу котирования УЖЕ хочется.
            //if (posMan.BlockTrading)
            //{
            //    //string msg = String.Format("[{0}] Trading is blocked. Please, change 'Block Trading' parameter.", m_optionPxMode);
            //    string msg = String.Format(RM.GetString("OptHandlerMsg.PositionsManager.TradingBlocked"), pxMode);
            //    m_context.Log(msg, MessageType.Info, true);
            //    return;
            //}

            InteractivePointActive tmp = eventArgs.Point;

            if ((tmp.Tag == null) || (!(tmp.Tag is PositionsManager.IvTargetInfo)))
            {
                string msg = String.Format("[{0}.ClickEvent] Denied #1", GetType().Name);
                m_context.Log(msg, MessageType.Warning, false);
                return;
            }

            {
                string msg = String.Format(CultureInfo.InvariantCulture, "[{0}.ClickEvent] Strike: {1}", GetType().Name, eventArgs.Point.ValueX);
                m_context.Log(msg, MessageType.Warning, false);
            }

            var ivTarget = tmp.Tag as PositionsManager.IvTargetInfo;

            // Передаю событие в PositionsManager
            //posMan.InteractiveSplineOnQuoteIvEvent(m_context, sender, eventArgs);
            // ОЧЕНЬ БОЛЬШОЙ ВОПРОС ЧТО БУДЕТ С КОНТЕКСТОМ ПРИ ЭТОМ???
            int res = posMan.CancelVolatility(m_context, ivTarget, "Left-click");

            if (res > 0)
            {
                string msg = String.Format(RM.GetString("OptHandlerMsg.PositionsManager.IvTargetCancelled"), pxMode, ivTarget);
                m_context.Log(msg, MessageType.Info, true, new Dictionary <string, object> {
                    { "VOLATILITY_ORDER_CANCELLED", msg }
                });

                // Вызываем принудительный пересчет агента, чтобы немедленно убрать заявку из стакана
                m_context.Recalc();
            }
        }
예제 #4
0
        internal static void FillNodeInfo(InteractivePointActive ip,
                                          double f, double dT, IOptionStrikePair sInfo,
                                          StrikeType optionType, OptionPxMode optPxMode,
                                          double optSigma, bool returnPct, bool isVisiblePoints, double riskfreeRatePct)
        {
            if (optionType == StrikeType.Any)
            {
                throw new ArgumentException("Option type 'Any' is not supported.", "optionType");
            }

            bool   isCall = (optionType == StrikeType.Call);
            double optPx  = FinMath.GetOptionPrice(f, sInfo.Strike, dT, optSigma, 0, isCall);

            // ReSharper disable once UseObjectOrCollectionInitializer
            SmileNodeInfo nodeInfo = new SmileNodeInfo();

            nodeInfo.F            = f;
            nodeInfo.dT           = dT;
            nodeInfo.RiskFreeRate = riskfreeRatePct;
            nodeInfo.Sigma        = returnPct ? optSigma * Constants.PctMult : optSigma;
            nodeInfo.OptPx        = optPx;
            nodeInfo.Strike       = sInfo.Strike;
            // Сюда мы приходим когда хотим торговать, поэтому обращение к Security уместно
            nodeInfo.Security   = (optionType == StrikeType.Put) ? sInfo.Put.Security : sInfo.Call.Security;
            nodeInfo.PxMode     = optPxMode;
            nodeInfo.OptionType = optionType;
            nodeInfo.Pair       = sInfo;
            //nodeInfo.ScriptTime = optTime;
            nodeInfo.CalendarTime = DateTime.Now;

            nodeInfo.Symbol   = nodeInfo.Security.Symbol;
            nodeInfo.DSName   = nodeInfo.Security.SecurityDescription.DSName;
            nodeInfo.Expired  = nodeInfo.Security.SecurityDescription.Expired;
            nodeInfo.FullName = nodeInfo.Security.SecurityDescription.FullName;

            ip.Tag          = nodeInfo;
            ip.Color        = AlphaColors.Yellow;
            ip.IsActive     = isVisiblePoints;
            ip.Geometry     = Geometries.Ellipse;
            ip.DragableMode = DragableMode.None;
            //ip.Value = new System.Windows.Point(sInfo.Strike, nodeInfo.Sigma);
            ip.Tooltip = String.Format(CultureInfo.InvariantCulture,
                                       "F:{0}; K:{1}; IV:{2:#0.00}%\r\n{3} px {4}",
                                       f, sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx);
        }
예제 #5
0
        protected static void FillNodeInfo(InteractivePointLight ip,
                                           double f, double dT, IOptionStrikePair sInfo,
                                           StrikeType optionType, OptionPxMode optPxMode,
                                           double optSigma, bool returnPct, double pctRate)
        {
            if (optionType == StrikeType.Any)
            {
                throw new ArgumentException("Option type 'Any' is not supported.", "optionType");
            }

            bool   isCall = (optionType == StrikeType.Call);
            double optPx  = FinMath.GetOptionPrice(f, sInfo.Strike, dT, optSigma, pctRate, isCall);

            // ReSharper disable once UseObjectOrCollectionInitializer
            SmileNodeInfo nodeInfo = new SmileNodeInfo();

            nodeInfo.F            = f;
            nodeInfo.dT           = dT;
            nodeInfo.RiskFreeRate = pctRate;
            nodeInfo.Sigma        = returnPct ? optSigma * Constants.PctMult : optSigma;
            nodeInfo.OptPx        = optPx;
            nodeInfo.Strike       = sInfo.Strike;
            nodeInfo.Security     = (optionType == StrikeType.Put) ? sInfo.Put.Security : sInfo.Call.Security;
            nodeInfo.PxMode       = optPxMode;
            nodeInfo.OptionType   = optionType;
            nodeInfo.Pair         = sInfo;
            //nodeInfo.ScriptTime = optTime;
            nodeInfo.CalendarTime = DateTime.Now;

            nodeInfo.Symbol   = nodeInfo.Security.Symbol;
            nodeInfo.DSName   = nodeInfo.Security.SecurityDescription.DSName;
            nodeInfo.FullName = nodeInfo.Security.SecurityDescription.FullName;
            nodeInfo.Expired  = nodeInfo.Security.SecurityDescription.Expired;

            ip.Tag   = nodeInfo;
            ip.Value = new Point(sInfo.Strike, nodeInfo.Sigma);

            if (ip is InteractivePointActive)
            {
                InteractivePointActive ipa = (InteractivePointActive)ip;
                ipa.Tooltip = String.Format("K:{0}; IV:{1:#0.00}%\r\n{2} {3} @ {4}",
                                            sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx, DefaultOptQty);
            }
        }
예제 #6
0
        protected static void FillNodeInfo(InteractivePointActive ip,
                                           double f, double dT, IOptionStrikePair sInfo,
                                           StrikeType optionType, OptionPxMode optPxMode,
                                           double optSigma, bool returnPct, bool isVisiblePoints)
        {
            if (optionType == StrikeType.Any)
            {
                throw new ArgumentException("Option type 'Any' is not supported.", "optionType");
            }

            bool   isCall = (optionType == StrikeType.Call);
            double optPx  = FinMath.GetOptionPrice(f, sInfo.Strike, dT, optSigma, 0, isCall);

            SmileNodeInfo nodeInfo = new SmileNodeInfo();

            nodeInfo.F          = f;
            nodeInfo.dT         = dT;
            nodeInfo.Sigma      = returnPct ? optSigma * Constants.PctMult : optSigma;
            nodeInfo.OptPx      = optPx;
            nodeInfo.Strike     = sInfo.Strike;
            nodeInfo.Security   = (optionType == StrikeType.Put) ? sInfo.Put.Security : sInfo.Call.Security;
            nodeInfo.PxMode     = optPxMode;
            nodeInfo.OptionType = optionType;
            nodeInfo.Pair       = sInfo;
            //nodeInfo.ScriptTime = optTime;
            nodeInfo.CalendarTime = DateTime.Now;

            nodeInfo.Symbol  = nodeInfo.Security.Symbol;
            nodeInfo.Expired = nodeInfo.Security.SecurityDescription.Expired;

            ip.Tag          = nodeInfo;
            ip.Color        = AlphaColors.Yellow;
            ip.IsActive     = isVisiblePoints;
            ip.Geometry     = Geometries.Ellipse;
            ip.DragableMode = DragableMode.None;
            //ip.Value = new System.Windows.Point(sInfo.Strike, nodeInfo.Sigma);
            ip.Tooltip = String.Format("F:{0}; K:{1}; IV:{2:#0.00}%\r\n{3} {4} @ {5}",
                                       f, sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx, DefaultOptQty);
        }
예제 #7
0
        private void InteractiveSplineOnQuoteIvEvent(object sender, InteractiveActionEventArgs eventArgs)
        {
            OptionPxMode pxMode = (m_qty > 0) ? OptionPxMode.Ask : OptionPxMode.Bid;

            PositionsManager posMan = PositionsManager.GetManager(m_context);

            if (posMan.BlockTrading)
            {
                //string msg = String.Format("[{0}] Trading is blocked. Please, change 'Block Trading' parameter.", m_optionPxMode);
                string msg = RM.GetStringFormat("OptHandlerMsg.PositionsManager.TradingBlocked", pxMode);
                m_context.Log(msg, MessageType.Info, true);
                return;
            }

            InteractivePointActive tmp = eventArgs.Point;

            if ((tmp == null) || (tmp.IsActive == null) || (!tmp.IsActive.Value) ||
                DoubleUtil.IsZero(m_qty))
            {
                //string msg = String.Format("[{0}] Unable to get direction of the order. Qty:{1}", pxMode, m_qty);
                string msg = RM.GetStringFormat("OptHandlerMsg.PositionsManager.UndefinedOrderDirection", pxMode, m_qty);
                m_context.Log(msg, MessageType.Error, true);
                return;
            }

            SmileNodeInfo nodeInfo = tmp.Tag as SmileNodeInfo;

            if (nodeInfo == null)
            {
                //string msg = String.Format("[{0}] There is no nodeInfo. Quote type: {1}; Strike: {2}", pxMode);
                string msg = RM.GetStringFormat(CultureInfo.InvariantCulture, "OptHandlerMsg.ThereIsNoNodeInfo",
                                                m_context.Runtime.TradeName, pxMode, eventArgs.Point.ValueX);
                m_context.Log(msg, MessageType.Error, true);
                return;
            }

            {
                string msg = String.Format(CultureInfo.InvariantCulture, "[{0}.ClickEvent] Strike: {1}", GetType().Name, tmp.ValueX);
                m_context.Log(msg, MessageType.Info, false);
            }

            nodeInfo.OptPx      = m_shiftIv;
            nodeInfo.ShiftOptPx = m_shiftPriceStep;
            nodeInfo.ClickTime  = DateTime.Now;
            nodeInfo.PxMode     = pxMode;

            // [2015-10-02] Подписка на данный инструмент, чтобы он появился в коллекции Context.Runtime.Securities
            var candids = (from s in Context.Runtime.Securities
                           where s.SecurityDescription.Name.Equals(nodeInfo.Symbol, StringComparison.InvariantCultureIgnoreCase)
                           select s).ToList();

            candids = (from s in candids
                       where s.SecurityDescription.DSName.Equals(nodeInfo.DSName, StringComparison.InvariantCultureIgnoreCase)
                       select s).ToList();
            ISecurity testSec = (from s in candids
                                 let secDesc = s.SecurityDescription
                                               where secDesc.FullName.Equals(nodeInfo.FullName, StringComparison.InvariantCultureIgnoreCase)
                                               select s).SingleOrDefault();

            if ((testSec == null) && (nodeInfo.Security != null))
            {
                ISecurity sec = nodeInfo.Security;
                int       bc  = sec.Bars.Count;
                string    msg = String.Format("[{0}] There is security DsName: {1}; Symbol: {2}; Security: {3} with {4} bars available.",
                                              pxMode, nodeInfo.DSName, nodeInfo.Symbol, nodeInfo.FullName, bc);
                Context.Log(msg, MessageType.Info, false);

                // Пересчитываю целочисленный параметр Qty в фактические лоты конкретного инструмента
                double actQty = Math.Abs(m_qty * sec.LotTick); // Модуль, потому что тут направление передается через PxMode
                nodeInfo.Qty = actQty;
            }
            else if ((nodeInfo.Pair != null) && (nodeInfo.Pair.Put != null))
            {
                // Аварийная ветка
                // Пересчитываю целочисленный параметр Qty в фактические лоты конкретного инструмента
                double actQty = Math.Abs(m_qty * nodeInfo.Pair.Put.LotTick); // Модуль, потому что тут направление передается через PxMode
                nodeInfo.Qty = actQty;
            }
            else
            {
                // Аварийная ветка
                // Не могу пересчитать целочисленный параметр Qty в фактические лоты конкретного инструмента!
                //double actQty = Math.Abs(m_qty * nodeInfo.Pair.Put.LotTick);
                nodeInfo.Qty = Math.Abs(m_qty); // Модуль, потому что тут направление передается через PxMode

                string msg = String.Format(CultureInfo.InvariantCulture, "[{0}.ClickEvent] LotTick will be set to 1.", GetType().Name);
                m_context.Log(msg, MessageType.Warning, false);
            }

            // Не страшно, если сюда пойдет null - posMan потом сам найдет нужный опцион
            nodeInfo.Security = testSec;

            // Передаю событие в PositionsManager
            //posMan.InteractiveSplineOnClickEvent(m_context, sender, eventArgs);
            posMan.InteractiveSplineOnQuoteIvEvent(m_context, sender, eventArgs);
        }
예제 #8
0
        /// <summary>
        /// Вычисление цены опциона различными способами. Есть возможность сразу сделать сдвиг цены (предусмотрены проверки).
        /// </summary>
        /// <param name="externalContext">Контекст блока для логгирования проблемы</param>
        /// <param name="f">Цена БА (нажна как верхняя оценка цены колла</param>
        /// <param name="sec">Инструмент</param>
        /// <param name="mode">алгоритм расчета (покупка, продажа, середина спреда)</param>
        /// <param name="shiftAsk">сдвиг асков</param>
        /// <param name="shiftBid">сдвиг бидов</param>
        /// <param name="qty">количество лотов в заявке</param>
        /// <param name="optTime">время получения этих котировок из рыночного провайдера</param>
        /// <returns>цена опциона (в случае проблем возвращает NaN)</returns>
        public static double GetOptPrice(IContext externalContext, double f, IOptionStrike sec, OptionPxMode mode,
                                         double shiftAsk, double shiftBid, out double qty, out DateTime optTime)
        {
            qty     = Double.NaN;
            optTime = new DateTime();
            double optPx = Double.NaN;

            // PROD-5952 - Не надо дергать стакан без нужды
            //sec.UpdateQueueData();
            if (mode == OptionPxMode.Ask)
            {
                if (/* sec.FinInfo.AskSize.HasValue && */ sec.FinInfo.Ask.HasValue)
                {
                    optPx   = sec.FinInfo.Ask.Value;
                    optTime = sec.FinInfo.LastUpdate;

                    qty = 0;
                    if (sec.FinInfo.AskSize.HasValue)
                    {
                        qty = sec.FinInfo.AskSize.Value;
                    }
                    else
                    {
                        // PROD-5952 - Не надо дергать стакан без нужды
                        //// Аски отсортированы по возрастанию
                        //var queue = sec.GetSellQueue(externalContext.BarsCount - 1);
                        //if ((queue != null) && (queue.Count > 0))
                        //{
                        //    IQueueData ask = queue[0]; // queue.First();
                        //    qty = ask.Quantity;
                        //}
                    }
                }
                else
                {
                    // PROD-5952 - Не надо дергать стакан без нужды
                    #region Нет данных в FinInfo
//                    // Аски отсортированы по возрастанию
//                    var queue = sec.GetSellQueue(externalContext.BarsCount - 1);
//                    if ((queue != null) && (queue.Count > 0))
//                    {
//                        IQueueData ask = queue[0]; // queue.First();

//#if DEBUG
//                        if (!s_conflictDate.ContainsKey(sec.Security.SecurityDescription.FullName))
//                        {
//                            bool check = (ask.Security.FullName == sec.Security.SecurityDescription.FullName);
//                            if (!check)
//                                s_conflictDate[sec.Security.SecurityDescription.FullName] = ask.LastUpdate;

//                            Debug.Assert(check,
//                                String.Format("Expected security: {0}; actual security: {1}",
//                                    sec.Security.SecurityDescription.FullName, ask.Security.FullName));
//                        }
//#endif

//                        optPx = ask.Price;
//                        qty = ask.Quantity;
//                        optTime = ask.LastUpdate;

//                        //string msg =
//                        //    String.Format(
//                        //        "[DEBUG:{0}] I was forced to use 'sec.GetSellQueue'. sec.Bars.Count:{1}; ask.LastUpdate:{2}; sec:{3}",
//                        //        typeof(IvSmile).Name, sec.Bars.Count,
//                        //        ask.LastUpdate.ToString(DateTimeFormatWithMs, CultureInfo.InvariantCulture),
//                        //        sec);
//                        //externalContext.Log(msg, MessageType.Warning, true);
//                    }
                    #endregion Нет данных в FinInfo
                }

                if (Double.IsNaN(optPx) || (optPx <= Double.Epsilon))
                {
                    optPx = 2 * f; // Это одна из верхних оценок цены опциона.
                }
                else
                {
                    optPx += shiftAsk;
                }
            }
            else if (mode == OptionPxMode.Bid)
            {
                if (/* sec.FinInfo.BidSize.HasValue && */ sec.FinInfo.Bid.HasValue)
                {
                    optPx   = sec.FinInfo.Bid.Value;
                    optTime = sec.FinInfo.LastUpdate;

                    qty = 0;
                    if (sec.FinInfo.BidSize.HasValue)
                    {
                        qty = sec.FinInfo.BidSize.Value;
                    }
                    else
                    {
                        // PROD-5952 - Не надо дергать стакан без нужды
                        //// Биды отсортированы ПО УБЫВАНИЮ!!!
                        //var queue = sec.GetBuyQueue(externalContext.BarsCount - 1);
                        //if ((queue != null) && (queue.Count > 0))
                        //{
                        //    IQueueData bid = queue[0]; // queue.First();
                        //    qty = bid.Quantity;
                        //}
                    }
                }
                else
                {
                    // PROD-5952 - Не надо дергать стакан без нужды
                    #region Нет данных в FinInfo
//                    // Биды отсортированы ПО УБЫВАНИЮ!!!
//                    var queue = sec.GetBuyQueue(externalContext.BarsCount - 1);
//                    if ((queue != null) && (queue.Count > 0))
//                    {
//                        IQueueData bid = queue[0]; // queue.First();

//#if DEBUG
//                        if (!s_conflictDate.ContainsKey(sec.Security.SecurityDescription.FullName))
//                        {
//                            bool check = (bid.Security.FullName == sec.Security.SecurityDescription.FullName);
//                            if (!check)
//                                s_conflictDate[sec.Security.SecurityDescription.FullName] = bid.LastUpdate;

//                            Debug.Assert(check,
//                                String.Format("Expected security: {0}; actual security: {1}",
//                                    sec.Security.SecurityDescription.FullName, bid.Security.FullName));
//                        }
//#endif

//                        optPx = bid.Price;
//                        qty = bid.Quantity;
//                        optPx -= shiftBid;
//                        optPx = Math.Max(optPx, 0);

//                        optTime = bid.LastUpdate;

//                        //string msg =
//                        //    String.Format(
//                        //        "[DEBUG:{0}] I was forced to use 'sec.GetSellQueue'. sec.Bars.Count:{1}; bid.LastUpdate:{2}; sec:{3}",
//                        //        typeof(IvSmile).Name, sec.Bars.Count,
//                        //        bid.LastUpdate.ToString(DateTimeFormatWithMs, CultureInfo.InvariantCulture),
//                        //        sec);
//                        //externalContext.Log(msg, MessageType.Warning, true);
//                    }
                    #endregion Нет данных в FinInfo
                }
            }
            else if (mode == OptionPxMode.Mid)
            {
                if (/* sec.FinInfo.BidSize.HasValue && */ sec.FinInfo.Bid.HasValue &&
                    /* sec.FinInfo.AskSize.HasValue && */ sec.FinInfo.Ask.HasValue)
                {
                    double askPx = sec.FinInfo.Ask.Value;
                    //double askQty = sec.FinInfo.AskSize.Value;
                    if (Double.IsNaN(askPx) || (askPx <= Double.Epsilon))
                    {
                        askPx = 2.0 * f; // Это одна из верхних оценок цены опциона.
                    }
                    else
                    {
                        askPx += shiftAsk;
                    }

                    double bidPx = sec.FinInfo.Bid.Value;
                    //double bidQty = sec.FinInfo.BidSize.Value;
                    bidPx -= shiftBid;
                    bidPx  = Math.Max(bidPx, 0);

                    optPx = (askPx + bidPx) / 2.0;
                    //qty = Math.Min(askQty, bidQty);

                    double askQty = 0, bidQty = 0;
                    #region AskQty
                    if (sec.FinInfo.AskSize.HasValue)
                    {
                        askQty = sec.FinInfo.AskSize.Value;
                    }
                    else
                    {
                        // PROD-5952 - Не надо дергать стакан без нужды
                        //// Аски отсортированы по возрастанию
                        //var queue = sec.GetSellQueue(externalContext.BarsCount - 1);
                        //if ((queue != null) && (queue.Count > 0))
                        //{
                        //    IQueueData ask = queue[0]; // queue.First();
                        //    askQty = ask.Quantity;
                        //}
                    }
                    #endregion AskQty

                    #region BidQty
                    if (sec.FinInfo.BidSize.HasValue)
                    {
                        bidQty = sec.FinInfo.BidSize.Value;
                    }
                    else
                    {
                        // PROD-5952 - Не надо дергать стакан без нужды
                        //// Биды отсортированы ПО УБЫВАНИЮ!!!
                        //var queue = sec.GetBuyQueue(externalContext.BarsCount - 1);
                        //if ((queue != null) && (queue.Count > 0))
                        //{
                        //    IQueueData bid = queue[0]; // queue.First();
                        //    bidQty = bid.Quantity;
                        //}
                    }
                    #endregion BidQty

                    qty = Math.Min(askQty, bidQty);

                    optTime = sec.FinInfo.LastUpdate;
                }
                else
                {
                    // PROD-5952 - Не надо дергать стакан без нужды
                    #region Нет данных в FinInfo
//                    var askQueue = sec.GetSellQueue(externalContext.BarsCount - 1);
//                    var bidQueue = sec.GetBuyQueue(externalContext.BarsCount - 1);
//                    if ((askQueue != null) && (askQueue.Count > 0) &&
//                        (bidQueue != null) && (bidQueue.Count > 0))
//                    {
//                        // Аски отсортированы по возрастанию
//                        IQueueData ask = askQueue[0]; // askQueue.First();

//#if DEBUG
//                        if (!s_conflictDate.ContainsKey(sec.Security.SecurityDescription.FullName))
//                        {
//                            bool check = (ask.Security.FullName == sec.Security.SecurityDescription.FullName);
//                            if (!check)
//                                s_conflictDate[sec.Security.SecurityDescription.FullName] = ask.LastUpdate;

//                            Debug.Assert(check,
//                                String.Format("Expected security: {0}; actual security: {1}",
//                                    sec.Security.SecurityDescription.FullName, ask.Security.FullName));
//                        }
//#endif

//                        double askPx = ask.Price;
//                        double askQty = ask.Quantity;
//                        if (Double.IsNaN(askPx) || (askPx <= Double.Epsilon))
//                            askPx = 2.0 * f; // Это одна из верхних оценок цены опциона.
//                        else
//                            askPx += shiftAsk;

//                        // Биды отсортированы ПО УБЫВАНИЮ!!!
//                        IQueueData bid = bidQueue[0]; // bidQueue.First();

//#if DEBUG
//                        if (!s_conflictDate.ContainsKey(sec.Security.SecurityDescription.FullName))
//                        {
//                            bool check = (bid.Security.FullName == sec.Security.SecurityDescription.FullName);
//                            if (!check)
//                                s_conflictDate[sec.Security.SecurityDescription.FullName] = bid.LastUpdate;

//                            Debug.Assert(check,
//                                String.Format("Expected security: {0}; actual security: {1}",
//                                    sec.Security.SecurityDescription.FullName, bid.Security.FullName));
//                        }
//#endif

//                        double bidPx = bid.Price;
//                        double bidQty = bid.Quantity;
//                        bidPx -= shiftBid;
//                        bidPx = Math.Max(bidPx, 0);

//                        optPx = (askPx + bidPx) / 2.0;
//                        qty = Math.Min(askQty, bidQty);

//                        optTime = (bid.LastUpdate < ask.LastUpdate) ? ask.LastUpdate : bid.LastUpdate;
//                    }
                    #endregion Нет данных в FinInfo
                }
            }
            else
            {
                throw new NotImplementedException("OptPxMode:" + mode);
            }

            return(optPx);
        }
예제 #9
0
        internal static void FillNodeInfo(InteractivePointActive ip,
                                          double f, double dT, IOptionStrikePair sInfo,
                                          StrikeType optionType, OptionPxMode optPxMode,
                                          double optPx, double optQty, double optSigma, DateTime optTime, bool returnPct, double riskfreeRatePct)
        {
            if (optionType == StrikeType.Any)
            {
                throw new ArgumentException("Option type 'Any' is not supported.", "optionType");
            }

            // ReSharper disable once UseObjectOrCollectionInitializer
            SmileNodeInfo nodeInfo = new SmileNodeInfo();

            nodeInfo.F            = f;
            nodeInfo.dT           = dT;
            nodeInfo.RiskFreeRate = riskfreeRatePct;
            nodeInfo.Sigma        = returnPct ? optSigma * Constants.PctMult : optSigma;
            nodeInfo.OptPx        = optPx;
            nodeInfo.Strike       = sInfo.Strike;
            // Сюда мы приходим когда хотим торговать, поэтому обращение к Security уместно
            nodeInfo.Security     = (optionType == StrikeType.Put) ? sInfo.Put.Security : sInfo.Call.Security;
            nodeInfo.PxMode       = optPxMode;
            nodeInfo.OptionType   = optionType;
            nodeInfo.Pair         = sInfo;
            nodeInfo.ScriptTime   = optTime;
            nodeInfo.CalendarTime = DateTime.Now;

            nodeInfo.Symbol   = nodeInfo.Security.Symbol;
            nodeInfo.DSName   = nodeInfo.Security.SecurityDescription.DSName;
            nodeInfo.Expired  = nodeInfo.Security.SecurityDescription.Expired;
            nodeInfo.FullName = nodeInfo.Security.SecurityDescription.FullName;

            ip.Tag          = nodeInfo;
            ip.DragableMode = DragableMode.None;
            ip.Value        = new Point(sInfo.Strike, nodeInfo.Sigma);
            // [2015-08-26] Алексей дал инструкцию убрать дату из тултипа.
            bool tooltipWithTime = false;

#if DEBUG
            tooltipWithTime = true;
#endif
            // [2015-12-07] В режиме отладки возвращаю.
            // Потому что иначе вообще непонятно что происходит и с какими данными скрипт работает.
            if (optQty > 0)
            {
                if (tooltipWithTime)
                {
                    ip.Tooltip = String.Format(CultureInfo.InvariantCulture, "K:{0}; IV:{1:#0.00}%\r\n{2} px {3} @ {4}\r\nDate: {5}",
                                               sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx, optQty,
                                               optTime.ToString(DateTimeFormatWithMs, CultureInfo.InvariantCulture));
                }
                else
                {
                    ip.Tooltip = String.Format(CultureInfo.InvariantCulture, "K:{0}; IV:{1:#0.00}%\r\n{2} px {3} @ {4}",
                                               sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx, optQty);
                }
            }
            else
            {
                if (tooltipWithTime)
                {
                    ip.Tooltip = String.Format(CultureInfo.InvariantCulture, "K:{0}; IV:{1:#0.00}%\r\n{2} px {3}\r\nDate: {4}",
                                               sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx,
                                               optTime.ToString(DateTimeFormatWithMs, CultureInfo.InvariantCulture));
                }
                else
                {
                    ip.Tooltip = String.Format(CultureInfo.InvariantCulture, "K:{0}; IV:{1:#0.00}%\r\n{2} px {3}",
                                               sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx);
                }
            }
        }