示例#1
0
        private int FillEditableCurve(SmileInfo info, List <InteractiveObject> controlPoints, List <double> xs, DragableMode dragMode)
        {
            if (xs.Count < 2)
            {
                string msg = String.Format("[DEBUG:{0}] Not enough points in argument xs. xs.Count:{0}", xs.Count);
                m_context.Log(msg, MessageType.Warning, true);
                return(0);
            }

            int    j          = 0;
            double k          = xs[0];
            double strikeStep = (xs[xs.Count - 1] - xs[0]) / (xs.Count - 1);

            while (k <= xs[xs.Count - 1])
            {
                if ((j < xs.Count) &&
                    (k <= xs[j]) && (xs[j] < k + strikeStep))
                {
                    #region Узел должен быть показан и доступен для редактирования
                    {
                        double sigma = info.ContinuousFunction.Value(xs[j]);

                        InteractivePointActive ip = new InteractivePointActive(xs[j], sigma);
                        ip.IsActive     = true;
                        ip.Geometry     = Geometries.Ellipse;
                        ip.DragableMode = dragMode;
                        ip.Color        = AlphaColors.GreenYellow;
                        ip.Tooltip      = String.Format("K:{0}; IV:{1:0.00}", xs[j], Constants.PctMult * sigma);

                        InteractiveObject obj = new InteractiveObject(ip);

                        controlPoints.Add(obj);
                    }
                    #endregion Узел должен быть показан и доступен для редактирования

                    j++;
                }
                else
                {
                    #region Просто точка без маркера
                    {
                        double sigma = info.ContinuousFunction.Value(k);

                        //InteractivePointActive ip = new InteractivePointActive(k, sigma);
                        //ip.IsActive = false;
                        //ip.Geometry = Geometries.Ellipse;
                        //ip.DragableMode = DragableMode.None;
                        //ip.Color = System.Windows.Media.Colors.Green;
                        //ip.Tooltip = String.Format("K:{0}; IV:{1:0.00}", k, Constants.PctMult * sigma);

                        InteractivePointLight ip  = new InteractivePointLight(k, sigma);
                        InteractiveObject     obj = new InteractiveObject(ip);

                        controlPoints.Add(obj);
                    }
                    #endregion Просто точка без маркера
                }

                k += strikeStep;
            }

            return(j);
        }
示例#2
0
        public InteractiveSeries Execute(double trueTimeToExpiry, InteractiveSeries smile, int barNum)
        {
            int barsCount = m_context.BarsCount;

            if (!m_context.IsLastBarUsed)
            {
                barsCount--;
            }
            if (barNum < barsCount - 1)
            {
                return(Constants.EmptySeries);
            }

            SmileInfo refSmileInfo = smile.GetTag <SmileInfo>();

            if ((refSmileInfo == null) || (refSmileInfo.ContinuousFunction == null))
            {
                return(Constants.EmptySeries);
            }

            if (Double.IsNaN(trueTimeToExpiry) || (trueTimeToExpiry < Double.Epsilon))
            {
                string msg = String.Format("[{0}] trueTimeToExpiry must be positive value. dT:{1}", GetType().Name, trueTimeToExpiry);
                m_context.Log(msg, MessageType.Error, true);
                return(Constants.EmptySeries);
            }

            InteractiveSeries res = FrozenSmile;

            // Поскольку редактируемые узлы идут с заданным шагом, то
            // допустим только режим Yonly.
            DragableMode dragMode = DragableMode.Yonly;
            SmileInfo    oldInfo  = res.GetTag <SmileInfo>();

            if (m_resetSmile ||
                (oldInfo == null) || (oldInfo.ContinuousFunction == null))
            {
                oldInfo = refSmileInfo;

                //oldInfo.F = sInfo.F;
                //oldInfo.dT = sInfo.dT;
                //oldInfo.RiskFreeRate = sInfo.RiskFreeRate;
            }

            double futPx = refSmileInfo.F;
            double dT    = trueTimeToExpiry;
            double ivAtm = refSmileInfo.ContinuousFunction.Value(futPx);

            SmileInfo info = new SmileInfo();
            {
                info.F            = futPx;
                info.dT           = trueTimeToExpiry;
                info.RiskFreeRate = oldInfo.RiskFreeRate;

                List <double>            xs           = new List <double>();
                List <double>            ys           = new List <double>();
                List <InteractiveObject> visibleNodes = (from oldObj in res.ControlPoints
                                                         where oldObj.AnchorIsActive
                                                         select oldObj).ToList();
                int visibleNodesCount = visibleNodes.Count;
                if (m_resetSmile || (visibleNodesCount != m_numberOfNodes))
                {
                    // Здесь обязательно в начале
                    //res.ControlPoints.Clear();
                    res.ControlPoints = new ReadOnlyCollection <InteractiveObject>(new InteractiveObject[0]);

                    int half = m_numberOfNodes / 2; // Целочисленное деление!

                    #region 1. Готовлю сплайн
                    {
                        double mult = m_nodeStep * ivAtm * Math.Sqrt(dT);
                        double dK   = futPx * (Math.Exp(mult) - 1);
                        // Сдвигаю точки, чтобы избежать отрицательных значений
                        while ((futPx - half * dK) <= Double.Epsilon)
                        {
                            half--;
                        }
                        for (int j = 0; j < m_numberOfNodes; j++)
                        {
                            double k = futPx + (j - half) * dK;
                            // Обычно здесь будет лежать сплайн от замороженной улыбки...
                            double sigma;
                            if ((!oldInfo.ContinuousFunction.TryGetValue(k, out sigma)) || Double.IsNaN(sigma))
                            {
                                string msg = String.Format("[DEBUG:{0}] Unable to get IV for strike:{1}. Please, try to decrease NodeStep.",
                                                           GetType().Name, k);
                                m_context.Log(msg, MessageType.Warning, true);
                                return(res);
                            }

                            xs.Add(k);
                            ys.Add(sigma);
                        }
                    }
                    #endregion 1. Готовлю сплайн
                }
                else
                {
                    // Здесь обязательно в начале
                    //res.ControlPoints.Clear();
                    res.ControlPoints = new ReadOnlyCollection <InteractiveObject>(new InteractiveObject[0]);

                    int half = m_numberOfNodes / 2; // Целочисленное деление!

                    #region 2. Готовлю сплайн
                    {
                        double mult = m_nodeStep * ivAtm * Math.Sqrt(dT);
                        double dK   = futPx * (Math.Exp(mult) - 1);
                        // Сдвигаю точки, чтобы избежать отрицательных значений
                        while ((futPx - half * dK) <= Double.Epsilon)
                        {
                            half--;
                        }

                        // внутренние узлы...
                        for (int j = 0; j < m_numberOfNodes; j++)
                        {
                            double k = futPx + (j - half) * dK;
                            //// Обычно здесь будет лежать сплайн от замороженной улыбки...
                            //double sigma = oldInfo.ContinuousFunction.Value(k);
                            double sigma = visibleNodes[j].Anchor.ValueY;

                            xs.Add(k);
                            ys.Add(sigma);
                        }
                    }
                    #endregion 2. Готовлю сплайн
                }

                try
                {
                    if (xs.Count >= BaseCubicSpline.MinNumberOfNodes)
                    {
                        NotAKnotCubicSpline spline = new NotAKnotCubicSpline(xs, ys);

                        info.ContinuousFunction   = spline;
                        info.ContinuousFunctionD1 = spline.DeriveD1();

                        //info.F = F;
                        //info.dT = trueTimeToExpiry;
                        res.Tag = info;
                    }
                }
                catch (Exception ex)
                {
                    m_context.Log(ex.ToString(), MessageType.Error, true);
                    return(Constants.EmptySeries);
                }

                // 2. Формирую кривую с более плотным шагом
                List <InteractiveObject> controlPoints = new List <InteractiveObject>();
                int editableNodesCount = FillEditableCurve(info, controlPoints, xs, dragMode);
                res.ControlPoints = new ReadOnlyCollection <InteractiveObject>(controlPoints);

                if (editableNodesCount != m_numberOfNodes)
                {
                    string msg = String.Format("[DEBUG:{0}] {1} nodes requested, but only {2} were prepared.",
                                               GetType().Name,
                                               m_numberOfNodes,
                                               editableNodesCount);
                    m_context.Log(msg, MessageType.Warning, true);
                }
            }

            if (!m_resetSmile)
            {
                if (m_loadSplineCoeffs)
                {
                }

                if (m_prepareSplineCoeffs)
                {
                    #region Prepare global spline
                    // Надо пересчитать сплайн в безразмерные коэффициенты

                    // Обновляю уровень IV ATM?
                    ivAtm = info.ContinuousFunction.Value(futPx);

                    SmileInfo globInfo = new SmileInfo();
                    globInfo.F            = futPx;
                    globInfo.dT           = trueTimeToExpiry;
                    globInfo.RiskFreeRate = oldInfo.RiskFreeRate;

                    StringBuilder sb = new StringBuilder(GlobalSmileKey);
                    sb.AppendLine();
                    sb.AppendFormat(CultureInfo.InvariantCulture, "F:{0}", futPx);
                    sb.AppendLine();
                    sb.AppendFormat(CultureInfo.InvariantCulture, "dT:{0}", dT);
                    sb.AppendLine();
                    sb.AppendFormat(CultureInfo.InvariantCulture, "IvAtm:{0}", ivAtm);
                    sb.AppendLine();
                    sb.AppendFormat(CultureInfo.InvariantCulture, "RiskFreeRate:{0}", globInfo.RiskFreeRate);
                    sb.AppendLine();
                    sb.AppendFormat(CultureInfo.InvariantCulture, "ShapePct:{0}", ShapePct);
                    sb.AppendLine();
                    sb.AppendLine("~~~");
                    sb.AppendFormat(CultureInfo.InvariantCulture, "X;Y");
                    sb.AppendLine();

                    //LogSimmetrizeFunc logSimmFunc = new LogSimmetrizeFunc(info.ContinuousFunction, F, 0.5);

                    List <double> xs = new List <double>();
                    List <double> ys = new List <double>();
                    foreach (InteractiveObject oldObj in res.ControlPoints)
                    {
                        if (!oldObj.AnchorIsActive)
                        {
                            continue;
                        }

                        double k = oldObj.Anchor.ValueX;
                        double x = Math.Log(k / futPx) / Math.Pow(dT, DefaultPow + m_shape) / ivAtm;

                        double sigma           = oldObj.Anchor.ValueY;
                        double sigmaNormalized = sigma / ivAtm;

                        xs.Add(x);
                        ys.Add(sigmaNormalized);

                        sb.AppendFormat(CultureInfo.InvariantCulture, "{0};{1}", x, sigmaNormalized);
                        sb.AppendLine();
                    }

                    try
                    {
                        NotAKnotCubicSpline globSpline = new NotAKnotCubicSpline(xs, ys);

                        globInfo.ContinuousFunction   = globSpline;
                        globInfo.ContinuousFunctionD1 = globSpline.DeriveD1();

                        //global.Tag = globInfo;

                        m_context.StoreGlobalObject(GlobalSmileKey, globInfo, true);

                        string msg = String.Format("[{0}] The globInfo was saved in Global cache as '{1}'.",
                                                   GetType().Name, GlobalSmileKey);
                        m_context.Log(msg, MessageType.Warning, true);

                        msg = String.Format("[{0}] The globInfo was saved in file tslab.log also. Smile:\r\n{1}",
                                            GetType().Name, sb);
                        m_context.Log(msg, MessageType.Info, true);

                        // Запись в клипбоард
                        try
                        {
                            //Thread thread = ThreadProfiler.Create(() => System.Windows.Clipboard.SetText(sb.ToString()));
                            XElement xel    = globInfo.ToXElement();
                            string   xelStr =
                                @"<?xml version=""1.0""?>
" + xel.AsString();
                            // PROD-5987 - Отключаю работу с клипбордом. Только пишу в tslab.log
                            //Thread thread = ThreadProfiler.Create(() => System.Windows.Clipboard.SetText(xelStr));
                            //thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
                            //thread.Start();
                            //thread.Join(); // Надо ли делать Join?

                            s_log.WarnFormat("Global smile info:\r\n\r\n{0}\r\n\r\n", xelStr);
                        }
                        catch (Exception clipEx)
                        {
                            m_context.Log(clipEx.ToString(), MessageType.Error, true);
                        }

                        m_context.Recalc();
                    }
                    catch (Exception ex)
                    {
                        m_context.Log(ex.ToString(), MessageType.Error, true);
                        //return Constants.EmptySeries;
                    }
                    #endregion Prepare global spline
                }
                else if (m_pasteGlobal)
                {
                    // PROD-5987 - Работа с клипбордом отключена. Функция вставки сейчас работать не будет.
                    m_context.Log($"[{GetType().Name}] Clipboard is not available. Sorry.", MessageType.Warning, true);

                    #region Paste spline from clipboard
                    //string xelStr = "";
                    //// Чтение из клипбоард
                    //try
                    //{
                    //    // PROD-5987 - Работа с клипбордом отключена. Функция вставки сейчас работать не будет.
                    //    ////Thread thread = ThreadProfiler.Create(() => System.Windows.Clipboard.SetText(sb.ToString()));
                    //    //Thread thread = ThreadProfiler.Create(() => xelStr = System.Windows.Clipboard.GetText());
                    //    //thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
                    //    //thread.Start();
                    //    //thread.Join(); // Надо ли делать Join?

                    //    if (!String.IsNullOrWhiteSpace(xelStr))
                    //    {
                    //        XDocument xDoc = XDocument.Parse(xelStr);
                    //        XElement xInfo = xDoc.Root;
                    //        SmileInfo templateSmile = SmileInfo.FromXElement(xInfo);

                    //        // Обновляю уровень IV ATM?
                    //        // TODO: перепроверить как работает редактирование шаблона
                    //        ivAtm = info.ContinuousFunction.Value(futPx);
                    //        if (Double.IsNaN(ivAtm))
                    //        {
                    //            ivAtm = refSmileInfo.ContinuousFunction.Value(futPx);

                    //            m_context.Log(String.Format("[DEBUG:{0}] ivAtm was NaN. I'll use value ivAtm:{1}", GetType().Name, ivAtm), MessageType.Warning, true);

                    //            if (Double.IsNaN(ivAtm))
                    //            {
                    //                throw new Exception(String.Format("[DEBUG:{0}] ivAtm is NaN.", GetType().Name));
                    //            }
                    //        }

                    //        templateSmile.F = futPx;
                    //        templateSmile.dT = trueTimeToExpiry;
                    //        templateSmile.RiskFreeRate = oldInfo.RiskFreeRate;

                    //        // Здесь обязательно в начале
                    //        //res.ControlPoints.Clear();
                    //        res.ControlPoints = new ReadOnlyCollection<InteractiveObject>(new InteractiveObject[0]);

                    //        SmileFunction5 func = new SmileFunction5(templateSmile.ContinuousFunction, templateSmile.ContinuousFunctionD1,
                    //            ivAtm, 0, 0, futPx, dT);
                    //        info.ContinuousFunction = func;
                    //        info.ContinuousFunctionD1 = func.DeriveD1();

                    //        // info уже лежит в Tag, поэтому при следующем пересчете сплайн уже должен пересчитаться
                    //        // по новой улыбке. Правильно?

                    //        string msg = String.Format("[DEBUG:{0}] SmileInfo was loaded from clipboard.", GetType().Name);
                    //        m_context.Log(msg, MessageType.Warning, true);

                    //        m_context.Recalc();
                    //    }
                    //}
                    //catch (Exception clipEx)
                    //{
                    //    m_context.Log(clipEx.ToString(), MessageType.Error, true);
                    //}
                    #endregion Paste spline from clipboard
                }
            }

            //res.ClickEvent -= res_ClickEvent;
            //res.ClickEvent += res_ClickEvent;
            //res.DragEvent -= res_DragEvent;
            //res.DragEvent += res_DragEvent;
            res.EndDragEvent -= res_EndDragEvent;
            res.EndDragEvent += res_EndDragEvent;

            return(res);
        }