示例#1
0
        private void Divide(Size constraint, out int realChildCount, out int optimalDivides, out double optimalDivideSize)
        {
            realChildCount    = optimalDivides = 0;
            optimalDivideSize = 0;

            foreach (UIElement child in InternalChildren)
            {
                if (child.Visibility != Visibility.Collapsed)
                {
                    realChildCount++;
                }
            }

            if (realChildCount == 0)
            {
                return;
            }

            IndexToSize indexToSize          = new IndexToSize(_orientation);
            double      curOptimalDivideSize = 0;

            int arrangeCount          = 0;
            int anotherDirDivideIndex = 0;

            for (int divideIndex = 1; divideIndex <= realChildCount; divideIndex++)
            {
                arrangeCount          = 0;
                anotherDirDivideIndex = 0;

                indexToSize.ResetMap();

                for (int childIndex = 0; childIndex < InternalChildren.Count; childIndex++)
                {
                    UIElement child = InternalChildren[childIndex];
                    if (child.Visibility == Visibility.Collapsed)
                    {
                        continue;
                    }

                    child.Measure(constraint);

                    indexToSize.UpdateDivideIndexToSizeMap(arrangeCount, child.DesiredSize);
                    indexToSize.UpdateAnotherDirDivideIndexToSizeMap(anotherDirDivideIndex, child.DesiredSize);

                    arrangeCount++;
                    if (arrangeCount == divideIndex)
                    {
                        curOptimalDivideSize = indexToSize.CurDivideOptimalSize;
                        if (!indexToSize.IsCurDivideOptimalSizeValid(curOptimalDivideSize, constraint))
                        {
                            break;
                        }

                        arrangeCount = 0;
                        anotherDirDivideIndex++;
                    }
                }

                curOptimalDivideSize = indexToSize.CurDivideOptimalSize;
                if (indexToSize.IsCurDivideOptimalSizeValid(curOptimalDivideSize, constraint) && DoubleUtil.GreaterThanOrClose(curOptimalDivideSize, optimalDivideSize))
                {
                    optimalDivideSize = curOptimalDivideSize;
                    optimalDivides    = divideIndex;

                    _columnIndexToWidthMap = indexToSize.GetColumnIndexToWidthMap;
                    _rowIndexToHeightMap   = indexToSize.GetRowIndexToHeightMap;
                }
            }
        }
示例#2
0
        /// <summary>
        /// Validate input value in RangeBase (Minimum, Maximum, and Value).
        /// </summary>
        /// <param name="value"></param>
        /// <returns>Returns False if value is NaN or NegativeInfinity or PositiveInfinity. Otherwise, returns True.</returns>
        private static bool IsValidDoubleValue(object value)
        {
            double d = (double)value;

            return(!(DoubleUtil.IsNaN(d) || double.IsInfinity(d)));
        }
示例#3
0
 public static double GetArrowSize([NotNull] System.Windows.Controls.MenuItem obj)
 {
     ValidationHelper.NotNull(obj, "obj");
     DoubleUtil.EnsureNonNegative();
     return(BoxingHelper <double> .Unbox(obj.GetValue(ArrowSizeProperty)));
 }
示例#4
0
        private static bool IsWrapWidthValid(object value)
        {
            double v = (double)value;

            return((DoubleUtil.IsNaN(v)) || (DoubleUtil.GreaterThanOrClose(v, 0d) && !Double.IsPositiveInfinity(v)));
        }
示例#5
0
 /// <summary>
 ///     Method which checks if mouse move is sufficient to start the drag
 /// </summary>
 private static bool CheckStartColumnHeaderDrag(Point currentPos, Point originalPos)
 {
     return(DoubleUtil.GreaterThan(Math.Abs(currentPos.X - originalPos.X), SystemParameters.MinimumHorizontalDragDistance));
 }
示例#6
0
        /// <summary>
        /// Internal helper function to find out the ratio of the distance from hitpoint to lineVector
        /// and the distance from lineVector to (lineVector+nextLine)
        /// </summary>
        /// <param name="linesVector">This is one edge of a polygonal node</param>
        /// <param name="nextLine">The connection vector between the same edge on biginNode and ednNode</param>
        /// <param name="hitPoint">a point</param>
        /// <returns>the relative position of hitPoint</returns>
        internal static double GetPositionBetweenLines(Vector linesVector, Vector nextLine, Vector hitPoint)
        {
            Vector nearestOnFirst = GetProjection(-hitPoint, linesVector - hitPoint);

            hitPoint = nextLine - hitPoint;
            Vector nearestOnSecond = GetProjection(hitPoint, hitPoint + linesVector);

            Vector shortest = nearestOnFirst - nearestOnSecond;

            System.Diagnostics.Debug.Assert((false == DoubleUtil.IsZero(shortest.X)) || (false == DoubleUtil.IsZero(shortest.Y)));

            //return DoubleUtil.IsZero(shortest.X) ? (nearestOnFirst.Y / shortest.Y) : (nearestOnFirst.X / shortest.X);
            return(Math.Sqrt(nearestOnFirst.LengthSquared / shortest.LengthSquared));
        }
        // Token: 0x06005F4C RID: 24396 RVA: 0x001AB894 File Offset: 0x001A9A94
        private static bool IsValidDoubleValue(object value)
        {
            double num = (double)value;

            return(!DoubleUtil.IsNaN(num) && !double.IsInfinity(num));
        }
        public double Execute(InteractiveSeries deltaProfile, IOptionSeries optSer, int barNum)
        {
            List <double> positionDeltas = m_context.LoadObject(VariableId + "positionDeltas") as List <double>;

            if (positionDeltas == null)
            {
                positionDeltas = new List <double>();
                m_context.StoreObject(VariableId + "positionDeltas", positionDeltas);
            }

            int len = m_context.BarsCount;

            if (len <= barNum)
            {
                string msg = String.Format("[{0}] (BarsCount <= barNum)! BarsCount:{1}; barNum:{2}",
                                           GetType().Name, m_context.BarsCount, barNum);
                m_context.Log(msg, MessageType.Info, true);
            }
            for (int j = positionDeltas.Count; j < Math.Max(len, barNum + 1); j++)
            {
                positionDeltas.Add(Constants.NaN);
            }

            {
                int barsCount = m_context.BarsCount;
                if (!m_context.IsLastBarUsed)
                {
                    barsCount--;
                }
                if ((barNum < barsCount - 1) || (optSer == null))
                {
                    return(positionDeltas[barNum]);
                }
            }

            if (deltaProfile == null)
            {
                return(Constants.NaN);
            }

            SmileInfo deltaInfo = deltaProfile.GetTag <SmileInfo>();

            if ((deltaInfo == null) || (deltaInfo.ContinuousFunction == null))
            {
                positionDeltas[barNum] = Double.NaN; // заполняю индекс barNumber
                return(Constants.NaN);
            }

            int      lastBarIndex   = optSer.UnderlyingAsset.Bars.Count - 1;
            DateTime now            = optSer.UnderlyingAsset.Bars[Math.Min(barNum, lastBarIndex)].Date;
            bool     wasInitialized = HandlerInitializedToday(now);

            double f  = deltaInfo.F;
            double dT = deltaInfo.dT;

            if (!DoubleUtil.IsPositive(dT))
            {
                // [{0}] Time to expiry must be positive value. dT:{1}
                string msg = RM.GetStringFormat("OptHandlerMsg.TimeMustBePositive", GetType().Name, dT);
                if (wasInitialized)
                {
                    m_context.Log(msg, MessageType.Error, true);
                }
                return(Constants.NaN);
            }

            if (!DoubleUtil.IsPositive(f))
            {
                // [{0}] Base asset price must be positive value. F:{1}
                string msg = RM.GetStringFormat("OptHandlerMsg.FutPxMustBePositive", GetType().Name, f);
                if (wasInitialized)
                {
                    m_context.Log(msg, MessageType.Error, true);
                }
                return(Constants.NaN);
            }

            double rawDelta;

            if (!deltaInfo.ContinuousFunction.TryGetValue(f, out rawDelta))
            {
                rawDelta = Constants.NaN;
            }

            positionDeltas[barNum] = rawDelta; // заполняю индекс barNumber

            m_delta.Value = rawDelta;
            if (PrintDeltaInLog)
            {
                m_context.Log(MsgId + ": " + m_delta.Value, MessageType.Info, PrintDeltaInLog);
            }

            if (m_hedgeDelta)
            {
                #region Hedge logic
                try
                {
                    int rounded = Math.Sign(rawDelta) * ((int)Math.Floor(Math.Abs(rawDelta)));
                    if (rounded == 0)
                    {
                        string msg = String.Format("[{0}] Delta is too low to hedge. Delta: {1}", MsgId, rawDelta);
                        m_context.Log(msg, MessageType.Info, true);
                    }
                    else
                    {
                        len = optSer.UnderlyingAsset.Bars.Count;
                        ISecurity sec = (from s in m_context.Runtime.Securities
                                         where (s.Symbol == optSer.UnderlyingAsset.Symbol)
                                         select s).SingleOrDefault();
                        if (sec == null)
                        {
                            string msg = String.Format("[{0}] There is no security. Symbol: {1}", MsgId, optSer.UnderlyingAsset.Symbol);
                            m_context.Log(msg, MessageType.Warning, true);
                        }
                        else
                        {
                            if (rounded < 0)
                            {
                                PositionsManager posMan     = PositionsManager.GetManager(m_context);
                                string           signalName = String.Format("\r\nDelta BUY\r\nF:{0}; dT:{1}; Delta:{2}\r\n", f, dT, rawDelta);
                                m_context.Log(signalName, MessageType.Warning, true);
                                posMan.BuyAtPrice(m_context, sec, Math.Abs(rounded), f, signalName, null);
                            }
                            else if (rounded > 0)
                            {
                                PositionsManager posMan     = PositionsManager.GetManager(m_context);
                                string           signalName = String.Format("\r\nDelta SELL\r\nF:{0}; dT:{1}; Delta:+{2}\r\n", f, dT, rawDelta);
                                m_context.Log(signalName, MessageType.Warning, true);
                                posMan.SellAtPrice(m_context, sec, Math.Abs(rounded), f, signalName, null);
                            }
                        }
                    }
                }
                finally
                {
                    m_hedgeDelta = false;
                }
                #endregion Hedge logic
            }

            SetHandlerInitialized(now);

            return(rawDelta);
        }
示例#9
0
        public double Execute(double price, double time, InteractiveSeries smile, IOptionSeries optSer, int barNum)
        {
            int barsCount = m_context.BarsCount;

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

            if ((smile == null) || (optSer == null))
            {
                return(Constants.NaN);
            }

            int      lastBarIndex   = optSer.UnderlyingAsset.Bars.Count - 1;
            DateTime now            = optSer.UnderlyingAsset.Bars[Math.Min(barNum, lastBarIndex)].Date;
            bool     wasInitialized = HandlerInitializedToday(now);

            double f  = price;
            double dT = time;

            if (!DoubleUtil.IsPositive(dT))
            {
                // [{0}] Time to expiry must be positive value. dT:{1}
                string msg = RM.GetStringFormat("OptHandlerMsg.TimeMustBePositive", GetType().Name, dT);
                if (wasInitialized)
                {
                    m_context.Log(msg, MessageType.Error, false);
                }
                return(Constants.NaN);
            }

            if (!DoubleUtil.IsPositive(f))
            {
                // [{0}] Base asset price must be positive value. F:{1}
                string msg = RM.GetStringFormat("OptHandlerMsg.FutPxMustBePositive", GetType().Name, f);
                if (wasInitialized)
                {
                    m_context.Log(msg, MessageType.Error, false);
                }
                return(Constants.NaN);
            }

            double rawVega, res;

            IOptionStrikePair[] pairs  = optSer.GetStrikePairs().ToArray();
            PositionsManager    posMan = PositionsManager.GetManager(m_context);

            if (SingleSeriesNumericalVega.TryEstimateVega(posMan, optSer, pairs, smile, m_greekAlgo, f, m_sigmaStep, dT, out rawVega))
            {
                // Переводим вегу в дифференциал 'изменение цены за 1% волы'.
                rawVega /= Constants.PctMult;

                res = rawVega;
            }
            else
            {
                res = Constants.NaN;
            }

            m_vega.Value = res;
            //context.Log(String.Format("[{0}] Delta: {1}; rawDelta:{2}", MsgId, delta.Value, rawDelta), logColor, true);

            SetHandlerInitialized(now);

            return(res);
        }
示例#10
0
        public double Execute(InteractiveSeries profile, int barNum)
        {
            // В данном случае намеренно возвращаю Double.NaN
            double failRes = Double.NaN;

            if (m_repeatLastValue)
            {
                failRes = Double.IsNaN(m_prevValue) ? Double.NaN : m_prevValue; // В данном случае намеренно возвращаю Double.NaN
            }
            Dictionary <DateTime, double> results;

            #region Get cache
            // [2019-01-30] Перевожу на использование NotClearableContainer (PROD-6683)
            string key       = m_variableId + "_results";
            var    container = m_context.LoadObject(key) as NotClearableContainer <Dictionary <DateTime, double> >;
            if (container != null)
            {
                results = container.Content;
            }
            else
            {
                results = m_context.LoadObject(key) as Dictionary <DateTime, double>; // Старая ветка на всякий случай
            }
            if (results == null)
            {
                string msg = String.Format(RM.GetString("OptHandlerMsg.GetValueAtm.CacheNotFound"),
                                           GetType().Name, key.GetHashCode());
                m_context.Log(msg, MessageType.Info);

                results   = new Dictionary <DateTime, double>();
                container = new NotClearableContainer <Dictionary <DateTime, double> >(results);
                m_context.StoreObject(key, container);
            }
            #endregion Get cache

            int len = m_context.BarsCount;
            if (len <= 0)
            {
                return(failRes);
            }

            // Вот так не работает. По всей видимости, это прямая индексация от утра
            //DateTime now = m_context.Runtime.GetBarTime(barNum);

            ISecurity sec = m_context.Runtime.Securities.FirstOrDefault();
            if ((sec == null) || (sec.Bars.Count <= barNum))
            {
                return(failRes);
            }

            DateTime now = sec.Bars[barNum].Date;
            double   rawRes;
            if (results.TryGetValue(now, out rawRes))
            {
                m_prevValue = rawRes;
                return(rawRes);
            }
            else
            {
                int barsCount = ContextBarsCount;
                if (barNum < barsCount - 1)
                {
                    // Если история содержит осмысленное значение, то оно уже содержится в failRes
                    return(failRes);
                }
                else
                {
                    #region Process last bar(s)
                    if (profile == null)
                    {
                        return(failRes);
                    }

                    SmileInfo profInfo = profile.GetTag <SmileInfo>();
                    if ((profInfo == null) || (profInfo.ContinuousFunction == null))
                    {
                        return(failRes);
                    }

                    double f  = profInfo.F;
                    double dT = profInfo.dT;
                    if (Double.IsNaN(f) || (f < Double.Epsilon))
                    {
                        string msg = String.Format(RM.GetString("OptHandlerMsg.FutPxMustBePositive"), GetType().Name, f);
                        m_context.Log(msg, MessageType.Error);
                        return(failRes);
                    }

                    if (!DoubleUtil.IsZero(m_moneyness))
                    {
                        if (Double.IsNaN(dT) || (dT < Double.Epsilon))
                        {
                            string msg = String.Format(RM.GetString("OptHandlerMsg.TimeMustBePositive"), GetType().Name, dT);
                            m_context.Log(msg, MessageType.Error);
                            return(failRes);
                        }
                    }

                    double effectiveF;
                    if (DoubleUtil.IsZero(m_moneyness))
                    {
                        effectiveF = f;
                    }
                    else
                    {
                        effectiveF = f * Math.Exp(m_moneyness * Math.Sqrt(profInfo.dT));
                    }
                    if (profInfo.ContinuousFunction.TryGetValue(effectiveF, out rawRes))
                    {
                        m_prevValue  = rawRes;
                        results[now] = rawRes;
                    }
                    else
                    {
                        rawRes = failRes;
                    }
                    #endregion Process last bar(s)

                    m_result.Value = rawRes;
                    m_context.Log(MsgId + ": " + m_result.Value, MessageType.Info, PrintInLog);

                    return(rawRes);
                }
            }
        }
示例#11
0
        /// <summary>
        /// Метод под флаг TemplateTypes.OPTION_SERIES, чтобы подключаться к источнику-серии
        /// </summary>
        public IList <double> Execute(IOptionSeries optSer)
        {
            List <double> res = m_context.LoadObject(VariableId + "Prices") as List <double>;

            if (res == null)
            {
                res = new List <double>();
                m_context.StoreObject(VariableId + "Prices", res);
            }

            int oldCount = res.Count;
            int len      = m_context.BarsCount;

            for (int j = oldCount; j < len; j++)
            {
                res.Add(Constants.NaN);
            }

            IOptionStrikePair pair = (from p in optSer.GetStrikePairs()
                                      where DoubleUtil.AreClose(p.Strike, m_strike)
                                      select p).FirstOrDefault();

            if (pair == null)
            {
                return(res);
            }
            var putBars  = pair.Put.Security.Bars;
            var callBars = pair.Call.Security.Bars;

            //if ((putBars.Count <= 0) || (callBars.Count <= 0))
            //    return res;

            ISecurity sec = optSer.UnderlyingAsset;

            // кеширование
            for (int j = oldCount; j < len; j++)
            {
                int putIndex  = Math.Min(putBars.Count - 1, j);
                int callIndex = Math.Min(callBars.Count - 1, j);
                if ((putIndex >= 0) && (callIndex >= 0) &&
                    (putBars[putIndex] is IBar) && (callBars[callIndex] is IBar))
                {
                    double putPx  = ((IBar)putBars[j]).TheoreticalPrice;
                    double callPx = ((IBar)callBars[j]).TheoreticalPrice;
                    double px     = callPx - putPx + pair.Strike;
                    res.Add(px);
                }
                else
                {
                    res.Add(Constants.NaN);
                }
            }

            // актуализирую текущее значение
            if ((len > 0) &&
                pair.PutFinInfo.TheoreticalPrice.HasValue && pair.CallFinInfo.TheoreticalPrice.HasValue)
            {
                double putPx  = pair.PutFinInfo.TheoreticalPrice.Value;
                double callPx = pair.CallFinInfo.TheoreticalPrice.Value;
                double px     = callPx - putPx + pair.Strike;

                res[res.Count - 1] = px;
            }

            return(res);
        }
示例#12
0
        /// <summary>
        /// Основной метод, который выполняет всю торговую логику по котированию и следит за риском
        /// </summary>
        protected double Process(double entryPermission,
                                 double strike, double risk, double maxRisk, InteractiveSeries smile, IOptionSeries optSer,
                                 double callRisk, double putRisk, int barNum)
        {
            int barsCount = m_context.BarsCount;

            if (!m_context.IsLastBarUsed)
            {
                barsCount--;
            }
            if ((barNum < barsCount - 1) || (optSer == null) || (smile == null))
            {
                return(Constants.NaN);
            }

            IOptionStrikePair pair;

            if (!optSer.TryGetStrikePair(strike, out pair))
            {
                return(Constants.NaN);
            }

            // Если риск не был измерен говорить вообще не о чем!
            if (Double.IsNaN(risk))
            {
                return(Constants.NaN);
            }

            // Если риск разумен и условие входа НЕ ВЫПОЛНЕНО -- отдыхаем.
            // А вот если риск превышен -- тогда по идее надо бы его подсократить!
            if ((risk < maxRisk) && (entryPermission <= 0))
            {
                return(Constants.NaN);
            }

            PositionsManager posMan = PositionsManager.GetManager(m_context);

            if (posMan.BlockTrading)
            {
                //string msg = String.Format("Trading is blocked. Please, change 'Block Trading' parameter.");
                //m_context.Log(msg, MessageType.Info, true);
                return(Constants.NaN);
            }

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

            if ((sInfo == null) || (sInfo.ContinuousFunction == null))
            {
                return(Constants.NaN);
            }

            double dT    = sInfo.dT;
            double futPx = sInfo.F;

            // Набираем риск
            if (risk < maxRisk)
            {
                double ivAtm;
                if ((!sInfo.ContinuousFunction.TryGetValue(strike, out ivAtm)) || Double.IsNaN(ivAtm) || (ivAtm < Double.Epsilon))
                {
                    string msg = String.Format("Unable to get IV at strike {0}. ivAtm:{1}", strike, ivAtm);
                    m_context.Log(msg, MessageType.Error, true);
                    return(Constants.NaN);
                }

                double theorPutPx  = FinMath.GetOptionPrice(futPx, strike, dT, ivAtm, 0, false);
                double theorCallPx = FinMath.GetOptionPrice(futPx, strike, dT, ivAtm, 0, true);

                #region Набираем риск
                double putPx, callPx;
                {
                    double   putQty, callQty;
                    DateTime putTime, callTime;
                    putPx  = IvSmile.GetOptPrice(m_context, futPx, pair.Put, OptionPxMode.Ask, 0, 0, out putQty, out putTime);
                    callPx = IvSmile.GetOptPrice(m_context, futPx, pair.Call, OptionPxMode.Ask, 0, 0, out callQty, out callTime);
                }

                if (m_optionType == StrikeType.Put)
                {
                    #region В путах
                    ISecurity sec = pair.Put.Security;
                    double    qty = Math.Abs(m_fixedQty);
                    qty = GetSafeQty(risk, maxRisk, qty, putRisk);
                    if (qty > 0)
                    {
                        double px      = SellOptions.SafeMinPrice(theorPutPx + m_entryShift * sec.Tick, putPx, sec);
                        double iv      = FinMath.GetOptionSigma(futPx, pair.Strike, dT, px, 0, false);
                        string sigName = String.Format("Risk:{0}; MaxRisk:{1}; Px:{2}; Qty:{3}; IV:{4:P2}; dT:{5}", risk, maxRisk, px, qty, iv, dT);
                        posMan.BuyAtPrice(m_context, sec, qty, px, "Open BUY", sigName);

                        m_context.Log(sigName, MessageType.Debug, false);
                    }
                    #endregion В путах
                }
                else if (m_optionType == StrikeType.Call)
                {
                    #region В колах
                    ISecurity sec = pair.Call.Security;
                    double    qty = Math.Abs(m_fixedQty);
                    qty = GetSafeQty(risk, maxRisk, qty, callRisk);
                    if (qty > 0)
                    {
                        double px      = SellOptions.SafeMinPrice(theorCallPx + m_entryShift * sec.Tick, callPx, sec);
                        double iv      = FinMath.GetOptionSigma(futPx, pair.Strike, dT, px, 0, true);
                        string sigName = String.Format("Risk:{0}; MaxRisk:{1}; Px:{2}; Qty:{3}; IV:{4:P2}; dT:{5}", risk, maxRisk, px, qty, iv, dT);
                        posMan.BuyAtPrice(m_context, sec, qty, px, "Open BUY", sigName);

                        m_context.Log(sigName, MessageType.Debug, false);
                    }
                    #endregion В колах
                }
                else
                {
                    #region В оба вида опционов сразу встаю
                    int executedQty = 0;
                    {
                        ISecurity sec = pair.Put.Security;
                        double    px  = SellOptions.SafeMinPrice(theorPutPx + m_entryShift * sec.Tick, putPx, sec);
                        double    iv  = FinMath.GetOptionSigma(futPx, pair.Strike, dT, px, 0, false);
                        double    qty = Math.Max(1, Math.Abs(m_fixedQty / 2));
                        qty = GetSafeQty(risk, maxRisk, qty, putRisk);
                        if (qty > 0)
                        {
                            string sigName = String.Format("Risk:{0}; MaxRisk:{1}; Px:{2}; Qty:{3}; IV:{4:P2}; dT:{5}", risk, maxRisk, px, qty, iv, dT);
                            posMan.BuyAtPrice(m_context, sec, qty, px, "Open BUY", sigName);

                            m_context.Log(sigName, MessageType.Debug, false);

                            executedQty += (int)qty;
                        }
                    }

                    if (Math.Abs(executedQty) < Math.Abs(m_fixedQty))
                    {
                        ISecurity sec = pair.Call.Security;
                        double    px  = SellOptions.SafeMinPrice(theorCallPx + m_entryShift * sec.Tick, callPx, sec);
                        double    iv  = FinMath.GetOptionSigma(futPx, pair.Strike, dT, px, 0, true);
                        double    qty = Math.Abs(m_fixedQty) - Math.Abs(executedQty);
                        // Делаю оценку изменения текущего риска, если нам зафилят заявку в путах
                        qty = GetSafeQty(risk + Math.Abs(executedQty) * putRisk, maxRisk, qty, callRisk);
                        if (qty > 0)
                        {
                            string sigName = String.Format("Risk:{0}; MaxRisk:{1}; Px:{2}; Qty:{3}; IV:{4:P2}; dT:{5}", risk, maxRisk, px, qty, iv, dT);
                            posMan.BuyAtPrice(m_context, sec, qty, px, "Open BUY", sigName);

                            m_context.Log(sigName, MessageType.Debug, false);

                            //executedQty += (int)qty;
                        }
                    }
                    #endregion В оба вида опционов сразу встаю
                }
                #endregion Набираем риск
            }
            else if (risk > maxRisk)
            {
                string msg;
                //string msg = String.Format("[DEBUG:{0}] risk:{1}; maxRisk:{2}", Context.Runtime.TradeName, risk, maxRisk);
                //m_context.Log(msg, MessageType.Debug, true);

                // Надо взять пары, начиная от центральной и далее по возрастанию расстояния
                var orderedPairs = (from p in optSer.GetStrikePairs()
                                    orderby Math.Abs(p.Strike - strike) ascending
                                    select p).ToArray();
                if (orderedPairs.Length > 0)
                {
                    foreach (IOptionStrikePair candidPair in orderedPairs)
                    {
                        #region Проверяю, что в страйке есть ДЛИННАЯ позиция
                        double putOpenQty  = posMan.GetTotalQty(candidPair.Put.Security, barNum);
                        double callOpenQty = posMan.GetTotalQty(candidPair.Call.Security, barNum);

                        if ((putOpenQty <= 0) && (callOpenQty <= 0))
                        {
                            continue;
                        }
                        if (DoubleUtil.IsZero(putOpenQty) && DoubleUtil.IsZero(callOpenQty))
                        {
                            continue;
                        }

                        {
                            msg = String.Format("[DEBUG:{0}] putOpenQty:{1}; callOpenQty:{2}", Context.Runtime.TradeName, putOpenQty, callOpenQty);
                            m_context.Log(msg, MessageType.Debug, true);
                        }
                        #endregion Проверяю, что в страйке есть ДЛИННАЯ позиция

                        double theorPutPx, theorCallPx;
                        {
                            double iv;
                            if ((!sInfo.ContinuousFunction.TryGetValue(candidPair.Strike, out iv)) || Double.IsNaN(iv) ||
                                (iv < Double.Epsilon))
                            {
                                msg = String.Format("Unable to get IV at strike {0}. IV:{1}", candidPair.Strike, iv);
                                m_context.Log(msg, MessageType.Error, true);
                                continue;
                            }

                            theorPutPx  = FinMath.GetOptionPrice(futPx, candidPair.Strike, dT, iv, 0, false);
                            theorCallPx = FinMath.GetOptionPrice(futPx, candidPair.Strike, dT, iv, 0, true);
                        }

                        #region Сдаём риск (один квант объёма за раз)
                        double putPx, callPx;
                        {
                            double   putQty, callQty;
                            DateTime putTime, callTime;
                            putPx  = IvSmile.GetOptPrice(m_context, futPx, candidPair.Put, OptionPxMode.Bid, 0, 0, out putQty, out putTime);
                            callPx = IvSmile.GetOptPrice(m_context, futPx, candidPair.Call, OptionPxMode.Bid, 0, 0, out callQty, out callTime);
                        }

                        if (m_optionType == StrikeType.Put)
                        {
                            #region В путах
                            if (putOpenQty > 0) // Это означает, что в страйке есть длинные путы
                            {
                                ISecurity sec     = candidPair.Put.Security;
                                double    px      = SellOptions.SafeMaxPrice(theorPutPx + m_exitShift * sec.Tick, putPx, sec);
                                double    iv      = FinMath.GetOptionSigma(futPx, candidPair.Strike, dT, px, 0, false);
                                double    qty     = Math.Min(Math.Abs(m_fixedQty), Math.Abs(putOpenQty));
                                string    sigName = String.Format("Risk:{0}; MaxRisk:{1}; Px:{2}; Qty:{3}; IV:{4:P2}; dT:{5}", risk, maxRisk, px, qty, iv, dT);
                                posMan.SellAtPrice(m_context, sec, qty, px, "Close SELL", sigName);

                                m_context.Log(sigName, MessageType.Debug, false);

                                // Выход из foreach (IOptionStrikePair candidPair in orderedPairs)
                                break;
                            }
                            #endregion В путах
                        }
                        else if (m_optionType == StrikeType.Call)
                        {
                            #region В колах
                            if (callOpenQty > 0) // Это означает, что в страйке есть длинные колы
                            {
                                ISecurity sec     = candidPair.Call.Security;
                                double    px      = SellOptions.SafeMaxPrice(theorCallPx + m_exitShift * sec.Tick, callPx, sec);
                                double    iv      = FinMath.GetOptionSigma(futPx, candidPair.Strike, dT, px, 0, true);
                                double    qty     = Math.Min(Math.Abs(m_fixedQty), Math.Abs(callOpenQty));
                                string    sigName = String.Format("Risk:{0}; MaxRisk:{1}; Px:{2}; Qty:{3}; IV:{4:P2}; dT:{5}", risk, maxRisk, px, qty, iv, dT);
                                posMan.SellAtPrice(m_context, sec, qty, px, "Close SELL", sigName);

                                m_context.Log(sigName, MessageType.Debug, false);

                                // Выход из foreach (IOptionStrikePair candidPair in orderedPairs)
                                break;
                            }
                            #endregion В колах
                        }
                        else
                        {
                            #region В оба вида опционов сразу встаю
                            int executedQty = 0;
                            if (putOpenQty > 0) // Это означает, что в страйке есть длинные путы
                            {
                                ISecurity sec     = candidPair.Put.Security;
                                double    px      = SellOptions.SafeMaxPrice(theorPutPx + m_exitShift * sec.Tick, putPx, sec);
                                double    iv      = FinMath.GetOptionSigma(futPx, candidPair.Strike, dT, px, 0, false);
                                double    qty     = Math.Min(Math.Abs(m_fixedQty), Math.Abs(putOpenQty));
                                string    sigName = String.Format("Risk:{0}; MaxRisk:{1}; Px:{2}; Qty:{3}; IV:{4:P2}; dT:{5}", risk, maxRisk, px, qty, iv, dT);
                                posMan.SellAtPrice(m_context, sec, qty, px, "Close SELL", sigName);

                                m_context.Log(sigName, MessageType.Debug, false);

                                executedQty += (int)qty;
                            }

                            if ((callOpenQty > 0) && // Это означает, что в страйке есть длинные колы
                                (Math.Abs(executedQty) < Math.Abs(m_fixedQty)))
                            {
                                ISecurity sec     = candidPair.Call.Security;
                                double    px      = SellOptions.SafeMaxPrice(theorCallPx + m_exitShift * sec.Tick, callPx, sec);
                                double    iv      = FinMath.GetOptionSigma(futPx, candidPair.Strike, dT, px, 0, true);
                                double    qty     = Math.Min(Math.Abs(m_fixedQty) - Math.Abs(executedQty), Math.Abs(callOpenQty));
                                string    sigName = String.Format("Risk:{0}; MaxRisk:{1}; Px:{2}; Qty:{3}; IV:{4:P2}; dT:{5}", risk, maxRisk, px, qty, iv, dT);
                                posMan.SellAtPrice(m_context, sec, qty, px, "Close SELL", sigName);

                                m_context.Log(sigName, MessageType.Debug, false);

                                executedQty += (int)qty;
                            }

                            if (executedQty > 0)
                            {
                                // Выход из foreach (IOptionStrikePair candidPair in orderedPairs)
                                break;
                            }
                            #endregion В оба вида опционов сразу встаю
                        }
                        #endregion Сдаём риск (один квант объёма за раз)
                    }
                }
                else
                {
                    msg = String.Format("[DEBUG:{0}] risk:{1}; maxRisk:{2}; orderedPairs.Length:{3}",
                                        Context.Runtime.TradeName, risk, maxRisk, orderedPairs.Length);
                    m_context.Log(msg, MessageType.Warning, true);
                }
            }

            return(Constants.NaN);
        }
示例#13
0
        /// <summary>
        /// Обработчик под тип входных данных OPTION_SERIES
        /// </summary>
        public InteractiveSeries Execute(IOptionSeries optSer, IList <double> rates)
        {
            InteractiveSeries res = m_context.LoadObject(VariableId + "theorSmile") as InteractiveSeries;

            if (res == null)
            {
                res = new InteractiveSeries(); // Здесь так надо -- мы делаем новую улыбку
                m_context.StoreObject(VariableId + "theorSmile", res);
            }

            if (optSer == null)
            {
                return(res);
            }

            int len = optSer.UnderlyingAsset.Bars.Count;

            if (len <= 0)
            {
                return(res);
            }

            FinInfo bSecFinInfo = optSer.UnderlyingAsset.FinInfo;

            if (!bSecFinInfo.LastPrice.HasValue)
            {
                return(res);
            }

            if (rates.Count <= 0)
            {
                //throw new ScriptException("There should be some values in second argument 'rates'.");
                return(res);
            }

            //IDataBar bar = optSer.UnderlyingAsset.Bars[len - 1];
            double futPx = bSecFinInfo.LastPrice.Value;
            // ФОРТС использует плоское календарное время
            DateTime optExpiry = optSer.ExpirationDate.Date.Add(m_expiryTime);
            double   dT        = (optExpiry - bSecFinInfo.LastUpdate).TotalYears();
            double   ratePct   = rates[rates.Count - 1];

            if (Double.IsNaN(dT) || (dT < Double.Epsilon))
            {
                // [{0}] Time to expiry must be positive value. dT:{1}
                string msg = RM.GetStringFormat("OptHandlerMsg.TimeMustBePositive", GetType().Name, dT);
                m_context.Log(msg, MessageType.Error, true);
                return(res);
            }

            if (Double.IsNaN(futPx) || (futPx < Double.Epsilon))
            {
                // [{0}] Base asset price must be positive value. F:{1}
                string msg = RM.GetStringFormat("OptHandlerMsg.FutPxMustBePositive", GetType().Name, futPx);
                m_context.Log(msg, MessageType.Error, true);
                return(res);
            }

            if (Double.IsNaN(ratePct))
            {
                //throw new ScriptException("Argument 'rate' contains NaN for some strange reason. rate:" + rate);
                return(res);
            }

            // TODO: переписаться на обновление старых значений
            //res.ControlPoints.Clear();
            List <InteractiveObject> controlPoints = new List <InteractiveObject>();

            List <double> xs = new List <double>();
            List <double> ys = new List <double>();

            IOptionStrikePair[] pairs = (from pair in optSer.GetStrikePairs()
                                         //orderby pair.Strike ascending -- уже отсортировано!
                                         select pair).ToArray();
            for (int j = 0; j < pairs.Length; j++)
            {
                bool showPoint          = true;
                IOptionStrikePair sInfo = pairs[j];
                double            k     = sInfo.Strike;
                //// Сверхдалекие страйки игнорируем
                //if ((sInfo.Strike < m_minStrike) || (m_maxStrike < sInfo.Strike))
                //{
                //    showPoint = false;
                //}

                if ((sInfo.PutFinInfo == null) || (sInfo.CallFinInfo == null) ||
                    (!sInfo.PutFinInfo.TheoreticalPrice.HasValue) || (!sInfo.PutFinInfo.Volatility.HasValue) ||
                    (sInfo.PutFinInfo.TheoreticalPrice.Value <= 0) || (sInfo.PutFinInfo.Volatility.Value <= 0) ||
                    (!sInfo.CallFinInfo.TheoreticalPrice.HasValue) || (!sInfo.CallFinInfo.Volatility.HasValue) ||
                    (sInfo.CallFinInfo.TheoreticalPrice.Value <= 0) || (sInfo.CallFinInfo.Volatility.Value <= 0))
                {
                    continue;
                }

                double prec;
                // Биржа шлет несогласованную улыбку
                //double virtualExchangeF = sInfo.CallFinInfo.TheoreticalPrice.Value - sInfo.PutFinInfo.TheoreticalPrice.Value + sInfo.Strike;
                if ((m_optionType == StrikeType.Any) || (m_optionType == StrikeType.Put))
                {
                    double optSigma = sInfo.PutFinInfo.Volatility.Value;
                    if ((!DoubleUtil.IsOne(m_multPx)) || (!DoubleUtil.IsZero(m_shiftPx)))
                    {
                        double optPx = sInfo.PutFinInfo.TheoreticalPrice.Value * m_multPx + m_shiftPx * sInfo.Tick;
                        if ((optPx <= 0) || (Double.IsNaN(optPx)))
                        {
                            optSigma = 0;
                        }
                        else
                        {
                            optSigma = FinMath.GetOptionSigma(futPx, k, dT, optPx, ratePct, false, out prec);
                        }
                    }

                    double vol = optSigma;

                    // ReSharper disable once UseObjectOrCollectionInitializer
                    InteractivePointActive ip = new InteractivePointActive(k, vol);
                    ip.Geometry = Geometries.Ellipse;
                    ip.Color    = AlphaColors.Cyan;
                    ip.Tooltip  = String.Format("K:{0}; IV:{1:0.00}", k, Constants.PctMult * optSigma);

                    if (showPoint && (vol > 0))
                    {
                        controlPoints.Add(new InteractiveObject(ip));
                    }

                    if ((xs.Count <= 0) ||
                        (!DoubleUtil.AreClose(k, xs[xs.Count - 1])))
                    {
                        xs.Add(k);
                        ys.Add(vol);
                    }
                }

                if ((m_optionType == StrikeType.Any) || (m_optionType == StrikeType.Call))
                {
                    double optSigma = sInfo.CallFinInfo.Volatility.Value;
                    if ((!DoubleUtil.IsOne(m_multPx)) || (!DoubleUtil.IsZero(m_shiftPx)))
                    {
                        double optPx = sInfo.CallFinInfo.TheoreticalPrice.Value * m_multPx + m_shiftPx * sInfo.Tick;
                        if ((optPx <= 0) || (Double.IsNaN(optPx)))
                        {
                            optSigma = 0;
                        }
                        else
                        {
                            optSigma = FinMath.GetOptionSigma(futPx, k, dT, optPx, ratePct, true, out prec);
                        }
                    }

                    double vol = optSigma;

                    // ReSharper disable once UseObjectOrCollectionInitializer
                    InteractivePointActive ip = new InteractivePointActive(k, vol);
                    ip.Geometry = Geometries.Ellipse;
                    ip.Color    = AlphaColors.DarkCyan;
                    ip.Tooltip  = String.Format("K:{0}; IV:{1:0.00}", k, Constants.PctMult * optSigma);

                    if (showPoint && (vol > 0))
                    {
                        controlPoints.Add(new InteractiveObject(ip));
                    }

                    if ((xs.Count <= 0) ||
                        (!DoubleUtil.AreClose(k, xs[xs.Count - 1])))
                    {
                        xs.Add(k);
                        ys.Add(vol);
                    }
                }
            }

            res.ControlPoints = new ReadOnlyCollection <InteractiveObject>(controlPoints);

            var      baseSec    = optSer.UnderlyingAsset;
            DateTime scriptTime = baseSec.Bars[baseSec.Bars.Count - 1].Date;

            // ReSharper disable once UseObjectOrCollectionInitializer
            SmileInfo info = new SmileInfo();

            info.F            = futPx;
            info.dT           = dT;
            info.Expiry       = optSer.ExpirationDate;
            info.ScriptTime   = scriptTime;
            info.RiskFreeRate = ratePct;
            info.BaseTicker   = baseSec.Symbol;

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

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

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

            return(res);
        }
示例#14
0
 private static bool IsInvalidDouble(double value)
 {
     return(Double.IsInfinity(value) ||
            DoubleUtil.IsNaN(value));
 }
 static CompassHandleDrawing()
 {
     HandleDrawing.RadiusProperty.OverrideMetadata(typeof(CompassHandleDrawing), new PaintDotNet.UI.FrameworkPropertyMetadata(DoubleUtil.GetBoxed(6.5)));
 }
        private void MoveChild(UIElement dragedChild)
        {
            var screenPos = new Win32.POINT();

            if (!Win32.GetCursorPos(ref screenPos))
            {
                return;
            }

            var posToPanel    = AssociatedObject.PointFromScreen(new Point(screenPos.X, screenPos.Y));
            var dragedElement = dragedChild as FrameworkElement;

            var childRect = new Rect(posToPanel.X - _cacheMouseDownToChildPos.X, DisabledYPosition ? _cacheChildToPanelPos.Y : (posToPanel.Y - _cacheMouseDownToChildPos.Y), dragedElement.ActualWidth, dragedElement.ActualHeight);

            //find the child which has max overlapping area with dragedChild
            Size?            maxOverlapSize  = null;
            FrameworkElement maxOverlapChild = null;

            foreach (FrameworkElement fe in AssociatedObject.Children)
            {
                if (fe == dragedElement)
                {
                    continue;
                }

                var sp          = fe.TranslatePoint(new Point(), AssociatedObject);
                var overlapSize = GetOverlapSize(new Rect(sp, new Point(sp.X + fe.ActualWidth, sp.Y + fe.ActualHeight)), childRect);

                if (overlapSize.IsEmpty)
                {
                    continue;
                }

                if (maxOverlapSize == null || DoubleUtil.GreaterThan(overlapSize.Width * overlapSize.Height, maxOverlapSize.Value.Width * maxOverlapSize.Value.Height))
                {
                    maxOverlapSize  = overlapSize;
                    maxOverlapChild = fe;
                }
            }

            //check the overlapping area whether match the exchanging child condition
            if (!maxOverlapSize.HasValue || maxOverlapSize.Value.IsEmpty)
            {
                return;
            }

            if (DoubleUtil.GreaterThanOrClose(maxOverlapSize.Value.Width, maxOverlapChild.ActualWidth / 2) && DoubleUtil.GreaterThanOrClose(maxOverlapSize.Value.Height, maxOverlapChild.ActualHeight / 2))
            {
                var targetIndex = AssociatedObject.Children.IndexOf(maxOverlapChild);

                if (IsFromItemsPanelTemplate)
                {
                    var sourceIndex = AssociatedObject.Children.IndexOf(dragedChild);

                    if (ItemsContainer.ItemsSource != null)
                    {
                        if (MoveItemFromItemsSource != null)
                        {
                            MoveItemFromItemsSource(sourceIndex, targetIndex);

                            //if use ObservableCollection.Move(...) to exchange position, follow code is unnecessary.
                            //else use ObservableCollection.RemoveAt(...) and ObservableCollection.Insert(...) to exchange position, follow code is necessary.
                            _dragedChild         = AssociatedObject.Children[targetIndex];
                            _dragedChild.Opacity = 0;
                        }
                    }
                    else
                    {
                        var sourceItem = ItemsContainer.Items[sourceIndex];

                        ItemsContainer.Items.RemoveAt(sourceIndex);
                        ItemsContainer.Items.Insert(targetIndex, sourceItem);

                        _dragedChild         = AssociatedObject.Children[targetIndex];
                        _dragedChild.Opacity = 0;
                    }
                }
                else
                {
                    AssociatedObject.Children.Remove(dragedChild);
                    AssociatedObject.Children.Insert(targetIndex, dragedChild);
                }
            }
        }
示例#17
0
        /// <summary>
        /// Finds out where the segment [hitBegin, hitEnd]
        /// is about the segment [orgBegin, orgEnd].
        /// </summary>
        internal static HitResult WhereIsSegmentAboutSegment(
            Vector hitBegin, Vector hitEnd, Vector orgBegin, Vector orgEnd)
        {
            if (hitEnd == hitBegin)
            {
                return(WhereIsCircleAboutSegment(hitBegin, new Vector(0, 0), orgBegin, orgEnd));
            }

            //----------------------------------------------------------------------
            // Source: http://isc.faqs.org/faqs/graphics/algorithms-faq/
            // Subject 1.03: How do I find intersections of 2 2D line segments?
            //
            // Let A,B,C,D be 2-space position vectors.  Then the directed line
            // segments AB & CD are given by:
            //
            // AB=A+r(B-A), r in [0,1]
            // CD=C+s(D-C), s in [0,1]
            //
            // If AB & CD intersect, then
            //
            // A+r(B-A)=C+s(D-C), or  Ax+r(Bx-Ax)=Cx+s(Dx-Cx)
            // Ay+r(By-Ay)=Cy+s(Dy-Cy)  for some r,s in [0,1]
            //
            // Solving the above for r and s yields
            //
            //      (Ay-Cy)(Dx-Cx)-(Ax-Cx)(Dy-Cy)
            //  r = -----------------------------  (eqn 1)
            //      (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
            //
            //      (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
            //  s = -----------------------------  (eqn 2)
            //      (Bx-Ax)(Dy-Cy)-(By-Ay)(Dx-Cx)
            //
            // Let P be the position vector of the intersection point, then
            //
            //  P=A+r(B-A) or Px=Ax+r(Bx-Ax) and Py=Ay+r(By-Ay)
            //
            // By examining the values of r & s, you can also determine some
            // other limiting conditions:
            //  If 0 <= r <= 1 && 0 <= s <= 1, intersection exists
            //  r < 0 or r > 1 or s < 0 or s > 1 line segments do not intersect
            //  If the denominator in eqn 1 is zero, AB & CD are parallel
            //  If the numerator in eqn 1 is also zero, AB & CD are collinear.
            //  If they are collinear, then the segments may be projected to the x-
            //  or y-axis, and overlap of the projected intervals checked.
            //
            // If the intersection point of the 2 lines are needed (lines in this
            // context mean infinite lines) regardless whether the two line
            // segments intersect, then
            //  If r > 1, P is located on extension of AB
            //  If r < 0, P is located on extension of BA
            //  If s > 1, P is located on extension of CD
            //  If s < 0, P is located on extension of DC
            // Also note that the denominators of eqn 1 & 2 are identical.
            //
            // References:
            // [O'Rourke (C)] pp. 249-51
            // [Gems III] pp. 199-202 "Faster Line Segment Intersection,"
            //----------------------------------------------------------------------
            // The result tells where the segment CD is about the vector AB.
            // Return "Right" if either C or D is not on the left from AB.
            HitResult result = HitResult.Right;

            // Calculate the vectors.
            Vector AB  = orgEnd - orgBegin;         // B - A
            Vector CA  = orgBegin - hitBegin;       // A - C
            Vector CD  = hitEnd - hitBegin;         // D - C
            double det = Vector.Determinant(AB, CD);

            if (DoubleUtil.IsZero(det))
            {
                // The segments are parallel.

                /*if (DoubleUtil.IsZero(Vector.Determinant(CD, CA)))
                 * {
                 *  // The segments are collinear.
                 *  // Check if their X and Y projections overlap.
                 *  if ((Math.Max(orgBegin.X, orgEnd.X) >= Math.Min(hitBegin.X, hitEnd.X)) &&
                 *      (Math.Min(orgBegin.X, orgEnd.X) <= Math.Max(hitBegin.X, hitEnd.X)) &&
                 *      (Math.Max(orgBegin.Y, orgEnd.Y) >= Math.Min(hitBegin.Y, hitEnd.Y)) &&
                 *      (Math.Min(orgBegin.Y, orgEnd.Y) <= Math.Max(hitBegin.Y, hitEnd.Y)))
                 *  {
                 *      // The segments overlap.
                 *      result = HitResult.Hit;
                 *  }
                 *  else if (false == DoubleUtil.IsZero(AB.X))
                 *  {
                 *      result = ((AB.X * CA.X) > 0) ? HitResult.Behind : HitResult.InFront;
                 *  }
                 *  else
                 *  {
                 *      result = ((AB.Y * CA.Y) > 0) ? HitResult.Behind : HitResult.InFront;
                 *  }
                 * }
                 * else */
                if (DoubleUtil.IsZero(Vector.Determinant(CD, CA)) || DoubleUtil.GreaterThan(Vector.Determinant(AB, CA), 0))
                {
                    // C is on the left from AB, and, since the segments are parallel, D is also on the left.
                    result = HitResult.Left;
                }
            }
            else
            {
                double r = AdjustFIndex(Vector.Determinant(AB, CA) / det);

                if (r > 0 && r < 1)
                {
                    // The line defined AB does cross the segment CD.
                    double s = AdjustFIndex(Vector.Determinant(CD, CA) / det);
                    if (s > 0 && s < 1)
                    {
                        // The crossing point is on the segment AB as well.
                        result = HitResult.Hit;
                    }
                    else
                    {
                        result = (0 < s) ? HitResult.InFront : HitResult.Behind;
                    }
                }
                else if ((WhereIsVectorAboutVector(hitBegin - orgBegin, AB) == HitResult.Left) ||
                         (WhereIsVectorAboutVector(hitEnd - orgBegin, AB) == HitResult.Left))
                {
                    // The line defined AB doesn't cross the segment CD, and neither C nor D
                    // is on the right from AB
                    result = HitResult.Left;
                }
            }

            return(result);
        }
示例#18
0
        ///
        /// Create the unmanaged resources
        ///
        internal override void FinalizeCreation()
        {
            _bitmapInit.EnsureInitializedComplete();
            BitmapSourceSafeMILHandle wicTransformer = null;

            double scaleX, scaleY;
            WICBitmapTransformOptions options;

            GetParamsFromTransform(Transform, out scaleX, out scaleY, out options);

            using (FactoryMaker factoryMaker = new FactoryMaker())
            {
                try
                {
                    IntPtr wicFactory = factoryMaker.ImagingFactoryPtr;

                    wicTransformer = _source.WicSourceHandle;

                    if (!DoubleUtil.IsOne(scaleX) || !DoubleUtil.IsOne(scaleY))
                    {
                        uint width  = Math.Max(1, (uint)(scaleX * _source.PixelWidth + 0.5));
                        uint height = Math.Max(1, (uint)(scaleY * _source.PixelHeight + 0.5));

                        HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapScaler(
                                          wicFactory,
                                          out wicTransformer));

                        lock (_syncObject)
                        {
                            HRESULT.Check(UnsafeNativeMethods.WICBitmapScaler.Initialize(
                                              wicTransformer,
                                              _source.WicSourceHandle,
                                              width,
                                              height,
                                              WICInterpolationMode.Fant));
                        }
                    }

                    if (options != WICBitmapTransformOptions.WICBitmapTransformRotate0)
                    {
                        // Rotations are extremely slow if we're pulling from a decoder because we end
                        // up decoding multiple times.  Caching the source lets us rotate faster at the cost
                        // of increased memory usage.
                        wicTransformer = CreateCachedBitmap(
                            null,
                            wicTransformer,
                            BitmapCreateOptions.PreservePixelFormat,
                            BitmapCacheOption.Default,
                            _source.Palette);
                        // BitmapSource.CreateCachedBitmap already calculates memory pressure for
                        // the new bitmap, so there's no need to do it before setting it to
                        // WicSourceHandle.

                        BitmapSourceSafeMILHandle rotator = null;

                        HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFlipRotator(
                                          wicFactory,
                                          out rotator));

                        lock (_syncObject)
                        {
                            HRESULT.Check(UnsafeNativeMethods.WICBitmapFlipRotator.Initialize(
                                              rotator,
                                              wicTransformer,
                                              options));
                        }

                        wicTransformer = rotator;
                    }

                    // If we haven't introduced either a scaler or rotator, add a null rotator
                    // so that our WicSourceHandle isn't the same as our Source's.
                    if (options == WICBitmapTransformOptions.WICBitmapTransformRotate0 &&
                        DoubleUtil.IsOne(scaleX) && DoubleUtil.IsOne(scaleY))
                    {
                        HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFlipRotator(
                                          wicFactory,
                                          out wicTransformer));

                        lock (_syncObject)
                        {
                            HRESULT.Check(UnsafeNativeMethods.WICBitmapFlipRotator.Initialize(
                                              wicTransformer,
                                              _source.WicSourceHandle,
                                              WICBitmapTransformOptions.WICBitmapTransformRotate0));
                        }
                    }

                    WicSourceHandle = wicTransformer;
                    _isSourceCached = _source.IsSourceCached;
                }
                catch
                {
                    _bitmapInit.Reset();
                    throw;
                }
            }

            CreationCompleted = true;
            UpdateCachedSettings();
        }
示例#19
0
 /// <summary>
 /// Clears double's computation fuzz around 0 and 1
 /// </summary>
 internal static double AdjustFIndex(double findex)
 {
     return(DoubleUtil.IsZero(findex) ? 0 : (DoubleUtil.IsOne(findex) ? 1 : findex));
 }
示例#20
0
 public bool Equals(double x, double y)
 {
     return(DoubleUtil.AreClose(x, y));
 }
示例#21
0
        // Update items size and positions
        private void Update(Size constraint)
        {
            var visibleGroups = this.Items.OfType <RibbonContextualTabGroup>()
                                .Where(group => group.InnerVisibility == Visibility.Visible && group.Items.Count > 0)
                                .ToList();

            var infinity = new Size(double.PositiveInfinity, double.PositiveInfinity);

            var canRibbonTabControlScroll = false;

            // Defensively try to find out if the RibbonTabControl can scroll
            if (visibleGroups.Count > 0)
            {
                var firstVisibleItem = visibleGroups.First().FirstVisibleItem;

                if (firstVisibleItem != null &&
                    firstVisibleItem.Parent != null)
                {
                    canRibbonTabControlScroll = ((RibbonTabControl)firstVisibleItem.Parent).CanScroll;
                }
            }

            if (visibleGroups.Count == 0 ||
                canRibbonTabControlScroll)
            {
                // Collapse itemRect
                itemsRect = new Rect(0, 0, 0, 0);
                // Set quick launch toolbar and header position and size
                quickAccessToolbarHolder.Measure(infinity);

                if (constraint.Width <= quickAccessToolbarHolder.DesiredSize.Width + 50)
                {
                    quickAccessToolbarRect = new Rect(0, 0, Math.Max(0, constraint.Width - 50), quickAccessToolbarHolder.DesiredSize.Height);
                    quickAccessToolbarHolder.Measure(quickAccessToolbarRect.Size);
                }

                if (constraint.Width > quickAccessToolbarHolder.DesiredSize.Width + 50)
                {
                    quickAccessToolbarRect = new Rect(0, 0, quickAccessToolbarHolder.DesiredSize.Width, quickAccessToolbarHolder.DesiredSize.Height);
                    headerHolder.Measure(infinity);
                    var allTextWidth = constraint.Width - quickAccessToolbarHolder.DesiredSize.Width;

                    if (HeaderAlignment == HorizontalAlignment.Left)
                    {
                        headerRect = new Rect(quickAccessToolbarHolder.DesiredSize.Width, 0, Math.Min(allTextWidth, headerHolder.DesiredSize.Width), constraint.Height);
                    }
                    else if (HeaderAlignment == HorizontalAlignment.Center)
                    {
                        headerRect = new Rect(quickAccessToolbarHolder.DesiredSize.Width + Math.Max(0, allTextWidth / 2 - headerHolder.DesiredSize.Width / 2), 0, Math.Min(allTextWidth, headerHolder.DesiredSize.Width), constraint.Height);
                    }
                    else if (HeaderAlignment == HorizontalAlignment.Right)
                    {
                        headerRect = new Rect(quickAccessToolbarHolder.DesiredSize.Width + Math.Max(0, allTextWidth - headerHolder.DesiredSize.Width), 0, Math.Min(allTextWidth, headerHolder.DesiredSize.Width), constraint.Height);
                    }
                    else if (HeaderAlignment == HorizontalAlignment.Stretch)
                    {
                        headerRect = new Rect(quickAccessToolbarHolder.DesiredSize.Width, 0, allTextWidth, constraint.Height);
                    }
                }
                else
                {
                    headerRect = new Rect(Math.Max(0, constraint.Width - 50), 0, 50, constraint.Height);
                }
            }
            else
            {
                // Set items container size and position
                var firstItem = visibleGroups.First().FirstVisibleItem;
                var lastItem  = visibleGroups.Last().LastVisibleItem;

                var startX = firstItem.TranslatePoint(new Point(0, 0), this).X;
                var endX   = lastItem.TranslatePoint(new Point(lastItem.DesiredSize.Width, 0), this).X;

                //Get minimum x point (workaround)
                foreach (var group in visibleGroups)
                {
                    firstItem = group.FirstVisibleItem;

                    if (firstItem != null)
                    {
                        if (firstItem.TranslatePoint(new Point(0, 0), this).X < startX)
                        {
                            startX = firstItem.TranslatePoint(new Point(0, 0), this).X;
                        }
                    }

                    lastItem = group.LastVisibleItem;

                    if (lastItem != null)
                    {
                        if (lastItem.TranslatePoint(new Point(lastItem.DesiredSize.Width, 0), this).X > endX)
                        {
                            endX = lastItem.TranslatePoint(new Point(lastItem.DesiredSize.Width, 0), this).X;
                        }
                    }
                }

                // Ensure that startX and endX are never negative
                startX = Math.Max(0, startX);
                endX   = Math.Max(0, endX);

                //Looks like thr titlebar things are ordered in an other way
                if (DoubleUtil.AreClose(startX, endX) == false)
                {
                    itemsRect = new Rect(startX, 0, Math.Max(0, Math.Min(endX, constraint.Width) - startX), constraint.Height);
                }

                // Set quick launch toolbar position and size
                quickAccessToolbarHolder.Measure(infinity);

                var quickAccessToolbarWidth = quickAccessToolbarHolder.DesiredSize.Width;
                quickAccessToolbarRect = new Rect(0, 0, Math.Min(quickAccessToolbarWidth, startX), quickAccessToolbarHolder.DesiredSize.Height);

                if (quickAccessToolbarWidth > startX)
                {
                    quickAccessToolbarHolder.Measure(quickAccessToolbarRect.Size);
                    quickAccessToolbarRect  = new Rect(0, 0, quickAccessToolbarHolder.DesiredSize.Width, quickAccessToolbarHolder.DesiredSize.Height);
                    quickAccessToolbarWidth = quickAccessToolbarHolder.DesiredSize.Width;
                }

                // Set header
                headerHolder.Measure(infinity);

                switch (HeaderAlignment)
                {
                case HorizontalAlignment.Left:
                {
                    if (startX - quickAccessToolbarWidth > 150)
                    {
                        var allTextWidth = startX - quickAccessToolbarWidth;
                        headerRect = new Rect(quickAccessToolbarRect.Width, 0, Math.Min(allTextWidth, headerHolder.DesiredSize.Width), constraint.Height);
                    }
                    else
                    {
                        var allTextWidth = Math.Max(0, constraint.Width - endX);
                        headerRect = new Rect(Math.Min(endX, constraint.Width), 0, Math.Min(allTextWidth, headerHolder.DesiredSize.Width), constraint.Height);
                    }
                }
                break;

                case HorizontalAlignment.Center:
                {
                    var allTextWidthRight   = Math.Max(0, constraint.Width - endX);
                    var allTextWidthLeft    = Math.Max(0, startX - quickAccessToolbarWidth);
                    var fitsRightButNotLeft = (allTextWidthRight >= headerHolder.DesiredSize.Width && allTextWidthLeft < headerHolder.DesiredSize.Width);

                    if (((startX - quickAccessToolbarWidth < 150 || fitsRightButNotLeft) && (startX - quickAccessToolbarWidth > 0) && (startX - quickAccessToolbarWidth < constraint.Width - endX)) || (endX < constraint.Width / 2))
                    {
                        headerRect = new Rect(Math.Min(Math.Max(endX, constraint.Width / 2 - headerHolder.DesiredSize.Width / 2), constraint.Width), 0, Math.Min(allTextWidthRight, headerHolder.DesiredSize.Width), constraint.Height);
                    }
                    else
                    {
                        headerRect = new Rect(quickAccessToolbarHolder.DesiredSize.Width + Math.Max(0, allTextWidthLeft / 2 - headerHolder.DesiredSize.Width / 2), 0, Math.Min(allTextWidthLeft, headerHolder.DesiredSize.Width), constraint.Height);
                    }
                }
                break;

                case HorizontalAlignment.Right:
                {
                    if (startX - quickAccessToolbarWidth > 150)
                    {
                        var allTextWidth = Math.Max(0, startX - quickAccessToolbarWidth);
                        headerRect = new Rect(quickAccessToolbarHolder.DesiredSize.Width + Math.Max(0, allTextWidth - headerHolder.DesiredSize.Width), 0, Math.Min(allTextWidth, headerHolder.DesiredSize.Width), constraint.Height);
                    }
                    else
                    {
                        var allTextWidth = Math.Max(0, constraint.Width - endX);
                        headerRect = new Rect(Math.Min(Math.Max(endX, constraint.Width - headerHolder.DesiredSize.Width), constraint.Width), 0, Math.Min(allTextWidth, headerHolder.DesiredSize.Width), constraint.Height);
                    }
                }
                break;

                case HorizontalAlignment.Stretch:
                {
                    if (startX - quickAccessToolbarWidth > 150)
                    {
                        var allTextWidth = startX - quickAccessToolbarWidth;
                        headerRect = new Rect(quickAccessToolbarRect.Width, 0, allTextWidth, constraint.Height);
                    }
                    else
                    {
                        var allTextWidth = Math.Max(0, constraint.Width - endX);
                        headerRect = new Rect(Math.Min(endX, constraint.Width), 0, allTextWidth, constraint.Height);
                    }
                }
                break;
                }
            }

            headerRect.Width = headerRect.Width + 2;
        }
示例#22
0
        private static void OnTickPlacementChanged(SliderEx slider, AvaloniaPropertyChangedEventArgs e)
        {
            if (slider.TopTickBar == null || slider.BottomTickBar == null)
            {
                return;
            }

            //strange behaviour in the view
            //right now we skip this
            if (slider.Orientation == Orientation.Vertical)
            {
                return;
            }

            //TopTickBar.Width = this.Width;
            //BottomTickBar.Width = this.Width;

            if (slider.Track?.Thumb != null)
            {
                switch (slider.Orientation)
                {
                case Orientation.Horizontal:
                    if (DoubleUtil.IsDoubleFinite(slider.Track.Thumb.Width))
                    {
                        slider.TopTickBar.ReservedSpace = slider.Track.Thumb.Width;
                    }
                    break;

                case Orientation.Vertical:
                    if (DoubleUtil.IsDoubleFinite(slider.Track.Thumb.Height))
                    {
                        slider.TopTickBar.ReservedSpace = slider.Track.Thumb.Height;
                    }
                    break;
                }
            }

            if (slider.Orientation == Orientation.Horizontal)
            {
                slider.Track.Thumb.Classes.Set("HorizontalSliderUpThumbStyle", slider.TickPlacement == TickPlacement.TopLeft);
                slider.Track.Thumb.Classes.Set("HorizontalSliderDownThumbStyle", slider.TickPlacement == TickPlacement.BottomRight);
            }
            else
            {
                slider.Track.Thumb.Classes.Set("VerticalSliderLeftThumbStyle", slider.TickPlacement == TickPlacement.TopLeft);
                slider.Track.Thumb.Classes.Set("VerticalSliderRightThumbStyle", slider.TickPlacement == TickPlacement.BottomRight);
            }

            TickPlacement tickBarPlacement = (TickPlacement)e.NewValue;

            switch (tickBarPlacement)
            {
            case TickPlacement.None:
                slider.TopTickBar.IsVisible    = false;
                slider.BottomTickBar.IsVisible = false;
                break;

            case TickPlacement.TopLeft:
                slider.TopTickBar.IsVisible = true;
                if (slider.Orientation == Orientation.Horizontal)
                {
                    slider.TrackBackground.Margin = new Thickness(5, 2, 5, 0);
                }
                else
                {
                    slider.TrackBackground.Margin = new Thickness(2, 5, 0, 5);
                }
                break;

            case TickPlacement.BottomRight:
                slider.BottomTickBar.IsVisible = true;
                if (slider.Orientation == Orientation.Horizontal)
                {
                    slider.TrackBackground.Margin = new Thickness(5, 2, 5, 0);
                }
                else
                {
                    slider.TrackBackground.Margin = new Thickness(0, 5, 2, 5);
                }
                break;

            case TickPlacement.Both:
                slider.TopTickBar.IsVisible    = true;
                slider.BottomTickBar.IsVisible = true;
                break;
            }
        }
示例#23
0
        /// <summary>
        /// Measure the content and store the desired size of the content
        /// </summary>
        /// <param name="constraint"></param>
        /// <returns></returns>
        protected override Size MeasureOverride(Size constraint)
        {
            Size curLineSize = new Size();

            _panelSize = new Size();
            _wrapWidth = double.IsNaN(WrapWidth) ? constraint.Width : WrapWidth;
            UIElementCollection children = InternalChildren;
            int childrenCount            = children.Count;

            // Add ToolBar items which have IsOverflowItem = true
            ToolBarPanel toolBarPanel = ToolBarPanel;

            if (toolBarPanel != null)
            {
                // Go through the generated items collection and add to the children collection
                // any that are marked IsOverFlowItem but aren't already in the children collection.
                //
                // The order of both collections matters.
                //
                // It is assumed that any children that were removed from generated items will have
                // already been removed from the children collection.
                List <UIElement> generatedItemsCollection = toolBarPanel.GeneratedItemsCollection;
                int generatedItemsCount = (generatedItemsCollection != null) ? generatedItemsCollection.Count : 0;
                int childrenIndex       = 0;
                for (int i = 0; i < generatedItemsCount; i++)
                {
                    UIElement child = generatedItemsCollection[i];
                    if ((child != null) && ToolBar.GetIsOverflowItem(child) && !(child is Separator))
                    {
                        if (childrenIndex < childrenCount)
                        {
                            if (children[childrenIndex] != child)
                            {
                                children.Insert(childrenIndex, child);
                                childrenCount++;
                            }
                        }
                        else
                        {
                            children.Add(child);
                            childrenCount++;
                        }
                        childrenIndex++;
                    }
                }

                Debug.Assert(childrenIndex == childrenCount, "ToolBarOverflowPanel.Children count mismatch after transferring children from GeneratedItemsCollection.");
            }

            // Measure all children to determine if we need to increase desired wrapWidth
            for (int i = 0; i < childrenCount; i++)
            {
                UIElement child = children[i] as UIElement;

                child.Measure(constraint);

                Size childDesiredSize = child.DesiredSize;
                if (DoubleUtil.GreaterThan(childDesiredSize.Width, _wrapWidth))
                {
                    _wrapWidth = childDesiredSize.Width;
                }
            }

            // wrapWidth should not be bigger than constraint.Width
            _wrapWidth = Math.Min(_wrapWidth, constraint.Width);

            for (int i = 0; i < children.Count; i++)
            {
                UIElement child = children[i] as UIElement;
                Size      sz    = child.DesiredSize;

                if (DoubleUtil.GreaterThan(curLineSize.Width + sz.Width, _wrapWidth)) //need to switch to another line
                {
                    _panelSize.Width   = Math.Max(curLineSize.Width, _panelSize.Width);
                    _panelSize.Height += curLineSize.Height;
                    curLineSize        = sz;

                    if (DoubleUtil.GreaterThan(sz.Width, _wrapWidth)) //the element is wider then the constraint - give it a separate line
                    {
                        _panelSize.Width   = Math.Max(sz.Width, _panelSize.Width);
                        _panelSize.Height += sz.Height;
                        curLineSize        = new Size();
                    }
                }
                else //continue to accumulate a line
                {
                    curLineSize.Width += sz.Width;
                    curLineSize.Height = Math.Max(sz.Height, curLineSize.Height);
                }
            }

            //the last line size, if any should be added
            _panelSize.Width   = Math.Max(curLineSize.Width, _panelSize.Width);
            _panelSize.Height += curLineSize.Height;

            return(_panelSize);
        }
示例#24
0
        /// <summary>
        /// Resize and resposition the SelectionRangeElement.
        /// </summary>
        private void UpdateSelectionRangeElementPositionAndSize()
        {
            Size trackSize = new Size(0d, 0d);
            Size thumbSize = new Size(0d, 0d);

            if (Track == null || DoubleUtil.LessThan(SelectionEnd, SelectionStart))
            {
                return;
            }

            trackSize = Track.DesiredSize; //Track.RenderSize;
            thumbSize = (Track.Thumb != null) ?
                                           /*Track.Thumb.RenderSize*/
                        Track.Thumb.DesiredSize : new Size(0d, 0d);

            double range = Maximum - Minimum;
            double valueToSize;

            Layoutable rangeElement = this.SelectionRangeElement as Layoutable;

            if (rangeElement == null)
            {
                return;
            }

            if (Orientation == Orientation.Horizontal)
            {
                // Calculate part size for HorizontalSlider
                if (DoubleUtil.AreClose(range, 0d) || (DoubleUtil.AreClose(trackSize.Width, thumbSize.Width)))
                {
                    valueToSize = 0d;
                }
                else
                {
                    valueToSize = Math.Max(0.0, (trackSize.Width - thumbSize.Width) / range);
                }

                rangeElement.Width = ((SelectionEnd - SelectionStart) * valueToSize);
                if (IsDirectionReversed)
                {
                    Canvas.SetLeft(rangeElement, (thumbSize.Width * 0.5) + Math.Max(Maximum - SelectionEnd, 0) * valueToSize);
                }
                else
                {
                    Canvas.SetLeft(rangeElement, (thumbSize.Width * 0.5) + Math.Max(SelectionStart - Minimum, 0) * valueToSize);
                }
            }
            else
            {
                // Calculate part size for VerticalSlider
                if (DoubleUtil.AreClose(range, 0d) || (DoubleUtil.AreClose(trackSize.Height, thumbSize.Height)))
                {
                    valueToSize = 0d;
                }
                else
                {
                    valueToSize = Math.Max(0.0, (trackSize.Height - thumbSize.Height) / range);
                }

                rangeElement.Height = ((SelectionEnd - SelectionStart) * valueToSize);
                if (IsDirectionReversed)
                {
                    Canvas.SetTop(rangeElement, (thumbSize.Height * 0.5) + Math.Max(SelectionStart - Minimum, 0) * valueToSize);
                }
                else
                {
                    Canvas.SetTop(rangeElement, (thumbSize.Height * 0.5) + Math.Max(Maximum - SelectionEnd, 0) * valueToSize);
                }
            }
        }
示例#25
0
        /// <summary>
        ///     Helper method to find display index, header and header start position based on given mouse position
        /// </summary>
        private void FindDisplayIndexAndHeaderPosition(Point startPos, bool findNearestColumn, out int displayIndex, out Point headerPos, out DataGridColumnHeader header)
        {
            Debug.Assert(ParentDataGrid != null, "ParentDataGrid is null");

            Point originPoint = new Point(0, 0);

            headerPos    = originPoint;
            displayIndex = -1;
            header       = null;

            if (startPos.X < 0.0)
            {
                if (findNearestColumn)
                {
                    displayIndex = 0;
                }

                return;
            }

            double   headerStartX       = 0.0;
            double   headerEndX         = 0.0;
            int      i                  = 0;
            DataGrid dataGrid           = ParentDataGrid;
            double   averageColumnWidth = dataGrid.InternalColumns.AverageColumnWidth;
            bool     firstVisibleNonFrozenColumnHandled = false;

            for (i = 0; i < dataGrid.Columns.Count; i++)
            {
                displayIndex++;
                DataGridColumnHeader currentHeader = dataGrid.ColumnHeaderFromDisplayIndex(i);
                if (currentHeader == null)
                {
                    DataGridColumn column = dataGrid.ColumnFromDisplayIndex(i);
                    if (!column.IsVisible)
                    {
                        continue;
                    }
                    else
                    {
                        headerStartX = headerEndX;
                        if (i >= dataGrid.FrozenColumnCount &&
                            !firstVisibleNonFrozenColumnHandled)
                        {
                            headerStartX -= dataGrid.HorizontalScrollOffset;
                            firstVisibleNonFrozenColumnHandled = true;
                        }

                        headerEndX = headerStartX + GetColumnEstimatedWidth(column, averageColumnWidth);
                    }
                }
                else
                {
                    GeneralTransform transform = currentHeader.TransformToAncestor(this);
                    headerStartX = transform.Transform(originPoint).X;
                    headerEndX   = headerStartX + currentHeader.RenderSize.Width;
                }

                if (DoubleUtil.LessThanOrClose(startPos.X, headerStartX))
                {
                    break;
                }

                if (DoubleUtil.GreaterThanOrClose(startPos.X, headerStartX) &&
                    DoubleUtil.LessThanOrClose(startPos.X, headerEndX))
                {
                    if (findNearestColumn)
                    {
                        double headerMidX = (headerStartX + headerEndX) * 0.5;
                        if (DoubleUtil.GreaterThanOrClose(startPos.X, headerMidX))
                        {
                            headerStartX = headerEndX;
                            displayIndex++;
                        }

                        if (_draggingSrcColumnHeader != null && _draggingSrcColumnHeader.Column != null && _draggingSrcColumnHeader.Column.DisplayIndex < displayIndex)
                        {
                            displayIndex--;
                        }
                    }
                    else
                    {
                        header = currentHeader;
                    }

                    break;
                }
            }

            if (i == dataGrid.Columns.Count)
            {
                displayIndex = dataGrid.Columns.Count - 1;
                headerStartX = headerEndX;
            }

            headerPos.X = headerStartX;
            return;
        }
示例#26
0
        // Sets Value = SnapToTick(value+direction), unless the result of SnapToTick is Value,
        // then it searches for the next tick greater(if direction is positive) than value
        // and sets Value to that tick
        private void MoveToNextTick(double direction)
        {
            if (direction != 0.0)
            {
                double value = this.Value;

                // Find the next value by snapping
                double next = SnapToTick(Math.Max(this.Minimum, Math.Min(this.Maximum, value + direction)));

                bool greaterThan = direction > 0; //search for the next tick greater than value?

                // If the snapping brought us back to value, find the next tick point
                if (next == value &&
                    !(greaterThan && value == Maximum) &&  // Stop if searching up if already at Max
                    !(!greaterThan && value == Minimum))    // Stop if searching down if already at Min
                {
                    // This property is rarely set so let's try to avoid the GetValue
                    // caching of the mutable default value
                    DoubleCollection ticks = null;

                    if (GetValue(TicksProperty)
                        != null)
                    {
                        ticks = Ticks;
                    }

                    // If ticks collection is available, use it.
                    // Note that ticks may be unsorted.
                    if ((ticks != null) && (ticks.Count > 0))
                    {
                        for (int i = 0; i < ticks.Count; i++)
                        {
                            double tick = ticks[i];

                            // Find the smallest tick greater than value or the largest tick less than value
                            if ((greaterThan && DoubleUtil.GreaterThan(tick, value) && (DoubleUtil.LessThan(tick, next) || next == value)) ||
                                (!greaterThan && DoubleUtil.LessThan(tick, value) && (DoubleUtil.GreaterThan(tick, next) || next == value)))
                            {
                                next = tick;
                            }
                        }
                    }
                    else if (DoubleUtil.GreaterThan(TickFrequency, 0.0))
                    {
                        // Find the current tick we are at
                        double tickNumber = Math.Round((value - Minimum) / TickFrequency);

                        if (greaterThan)
                        {
                            tickNumber += 1.0;
                        }
                        else
                        {
                            tickNumber -= 1.0;
                        }

                        next = Minimum + tickNumber * TickFrequency;
                    }
                }

                // Update if we've found a better value
                if (next != value)
                {
                    this.SetValue(ValueProperty, next);
                }
            }
        }
        // Parse a FigureLength from a string given the CultureInfo.
        static internal void FromString(
            string s,
            CultureInfo cultureInfo,
            out double value,
            out FigureUnitType unit)
        {
            string goodString = s.Trim().ToLowerInvariant();

            value = 0.0;
            unit  = FigureUnitType.Pixel;

            int    i;
            int    strLen     = goodString.Length;
            int    strLenUnit = 0;
            double unitFactor = 1.0;

            //  this is where we would handle trailing whitespace on the input string.
            //  peel [unit] off the end of the string
            i = 0;

            if (goodString == UnitStrings[i].Name)
            {
                strLenUnit = UnitStrings[i].Name.Length;
                unit       = UnitStrings[i].UnitType;
            }
            else
            {
                for (i = 1; i < UnitStrings.Length; ++i)
                {
                    //  Note: this is NOT a culture specific comparison.
                    //  this is by design: we want the same unit string table to work across all cultures.
                    if (goodString.EndsWith(UnitStrings[i].Name, StringComparison.Ordinal))
                    {
                        strLenUnit = UnitStrings[i].Name.Length;
                        unit       = UnitStrings[i].UnitType;
                        break;
                    }
                }
            }

            //  we couldn't match a real unit from FigureUnitTypes.
            //  try again with a converter-only unit (a pixel equivalent).
            if (i >= UnitStrings.Length)
            {
                for (i = 0; i < PixelUnitStrings.Length; ++i)
                {
                    //  Note: this is NOT a culture specific comparison.
                    //  this is by design: we want the same unit string table to work across all cultures.
                    if (goodString.EndsWith(PixelUnitStrings[i], StringComparison.Ordinal))
                    {
                        strLenUnit = PixelUnitStrings[i].Length;
                        unitFactor = PixelUnitFactors[i];
                        break;
                    }
                }
            }

            //  this is where we would handle leading whitespace on the input string.
            //  this is also where we would handle whitespace between [value] and [unit].
            //  check if we don't have a [value].  This is acceptable for certain UnitTypes.
            if (strLen == strLenUnit && unit != FigureUnitType.Pixel)

            {
                value = 1;
            }
            //  we have a value to parse.
            else
            {
                Debug.Assert(unit == FigureUnitType.Pixel ||
                             DoubleUtil.AreClose(unitFactor, 1.0));

                string valueString = goodString.Substring(0, strLen - strLenUnit);
                value = Convert.ToDouble(valueString, cultureInfo) * unitFactor;
            }
        }
示例#28
0
        /// <summary>
        /// Verify all text formatting arguments
        /// </summary>
        private void VerifyTextFormattingArguments(
            TextSource textSource,
            int firstCharIndex,
            double paragraphWidth,
            TextParagraphProperties paragraphProperties,
            TextRunCache textRunCache
            )
        {
            if (textSource == null)
            {
                throw new ArgumentNullException("textSource");
            }

            if (textRunCache == null)
            {
                throw new ArgumentNullException("textRunCache");
            }

            if (paragraphProperties == null)
            {
                throw new ArgumentNullException("paragraphProperties");
            }

            if (paragraphProperties.DefaultTextRunProperties == null)
            {
                throw new ArgumentNullException("paragraphProperties.DefaultTextRunProperties");
            }

            if (paragraphProperties.DefaultTextRunProperties.Typeface == null)
            {
                throw new ArgumentNullException("paragraphProperties.DefaultTextRunProperties.Typeface");
            }

            if (DoubleUtil.IsNaN(paragraphWidth))
            {
                throw new ArgumentOutOfRangeException("paragraphWidth", SR.Get(SRID.ParameterValueCannotBeNaN));
            }

            if (double.IsInfinity(paragraphWidth))
            {
                throw new ArgumentOutOfRangeException("paragraphWidth", SR.Get(SRID.ParameterValueCannotBeInfinity));
            }

            if (paragraphWidth < 0 ||
                paragraphWidth > Constants.RealInfiniteWidth)
            {
                throw new ArgumentOutOfRangeException("paragraphWidth", SR.Get(SRID.ParameterMustBeBetween, 0, Constants.RealInfiniteWidth));
            }

            double realMaxFontRenderingEmSize = Constants.RealInfiniteWidth / Constants.GreatestMutiplierOfEm;

            if (paragraphProperties.DefaultTextRunProperties.FontRenderingEmSize < 0 ||
                paragraphProperties.DefaultTextRunProperties.FontRenderingEmSize > realMaxFontRenderingEmSize)
            {
                throw new ArgumentOutOfRangeException("paragraphProperties.DefaultTextRunProperties.FontRenderingEmSize", SR.Get(SRID.ParameterMustBeBetween, 0, realMaxFontRenderingEmSize));
            }

            if (paragraphProperties.Indent > Constants.RealInfiniteWidth)
            {
                throw new ArgumentOutOfRangeException("paragraphProperties.Indent", SR.Get(SRID.ParameterCannotBeGreaterThan, Constants.RealInfiniteWidth));
            }

            if (paragraphProperties.LineHeight > Constants.RealInfiniteWidth)
            {
                throw new ArgumentOutOfRangeException("paragraphProperties.LineHeight", SR.Get(SRID.ParameterCannotBeGreaterThan, Constants.RealInfiniteWidth));
            }

            if (paragraphProperties.DefaultIncrementalTab < 0 ||
                paragraphProperties.DefaultIncrementalTab > Constants.RealInfiniteWidth)
            {
                throw new ArgumentOutOfRangeException("paragraphProperties.DefaultIncrementalTab", SR.Get(SRID.ParameterMustBeBetween, 0, Constants.RealInfiniteWidth));
            }
        }
示例#29
0
        override protected bool IsOffscreenCore()
        {
            if (!Owner.IsVisible)
            {
                return(true);
            }

            Rect boundingRect = DataGridAutomationPeer.CalculateVisibleBoundingRect(this.Owner);

            return(DoubleUtil.AreClose(boundingRect, Rect.Empty) || DoubleUtil.AreClose(boundingRect.Height, 0.0) || DoubleUtil.AreClose(boundingRect.Width, 0.0));
        }
示例#30
0
 internal bool IsCurDivideOptimalSizeValid(double curDivideOptimalSize, Size size)
 {
     return(DoubleUtil.LessThanOrClose(curDivideOptimalSize, _orientation == Orientation.Horizontal ? size.Width : size.Height));
 }