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; } } }
/// <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))); }
public static double GetArrowSize([NotNull] System.Windows.Controls.MenuItem obj) { ValidationHelper.NotNull(obj, "obj"); DoubleUtil.EnsureNonNegative(); return(BoxingHelper <double> .Unbox(obj.GetValue(ArrowSizeProperty))); }
private static bool IsWrapWidthValid(object value) { double v = (double)value; return((DoubleUtil.IsNaN(v)) || (DoubleUtil.GreaterThanOrClose(v, 0d) && !Double.IsPositiveInfinity(v))); }
/// <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)); }
/// <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); }
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); }
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); } } }
/// <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); }
/// <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); }
/// <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); }
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); } } }
/// <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); }
/// /// 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(); }
/// <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)); }
public bool Equals(double x, double y) { return(DoubleUtil.AreClose(x, y)); }
// 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; }
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; } }
/// <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); }
/// <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); } } }
/// <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; }
// 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; } }
/// <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)); } }
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)); }
internal bool IsCurDivideOptimalSizeValid(double curDivideOptimalSize, Size size) { return(DoubleUtil.LessThanOrClose(curDivideOptimalSize, _orientation == Orientation.Horizontal ? size.Width : size.Height)); }