protected override double EaseInCore(double normalizedTime)
        {
            // The math below is complicated because we have a few requirements to get the correct look for bounce:
            //  1) The bounces should be symetrical
            //  2) Bounciness should control both the amplitude and the period of the bounces
            //  3) Bounces should control the number of bounces without including the final half bounce to get you back to 1.0
            //
            //  Note: Simply modulating a expo or power curve with a abs(sin(...)) wont work because it violates 1) above.
            //

            // Constants
            double bounces    = Math.Max(0.0, (double)Bounces);
            double bounciness = Bounciness;

            // Clamp the bounciness so we dont hit a divide by zero
            if (bounciness < 1.0 || DoubleUtil.IsOne(bounciness))
            {
                // Make it just over one.  In practice, this will look like 1.0 but avoid divide by zeros.
                bounciness = 1.001;
            }

            double pow = Math.Pow(bounciness, bounces);
            double oneMinusBounciness = 1.0 - bounciness;

            // 'unit' space calculations.
            // Our bounces grow in the x axis exponentially.  we define the first bounce as having a 'unit' width of 1.0 and compute
            // the total number of 'units' using a geometric series.
            // We then compute which 'unit' the current time is in.
            double sumOfUnits = (1.0 - pow) / oneMinusBounciness + pow * 0.5; // geometric series with only half the last sum
            double unitAtT    = normalizedTime * sumOfUnits;

            // 'bounce' space calculations.
            // Now that we know which 'unit' the current time is in, we can determine which bounce we're in by solving the geometric equation:
            // unitAtT = (1 - bounciness^bounce) / (1 - bounciness), for bounce.
            double bounceAtT = Math.Log(-unitAtT * (1.0 - bounciness) + 1.0, bounciness);
            double start     = Math.Floor(bounceAtT);
            double end       = start + 1.0;

            // 'time' space calculations.
            // We then project the start and end of the bounce into 'time' space
            double startTime = (1.0 - Math.Pow(bounciness, start)) / (oneMinusBounciness * sumOfUnits);
            double endTime   = (1.0 - Math.Pow(bounciness, end)) / (oneMinusBounciness * sumOfUnits);

            // Curve fitting for bounce.
            double midTime            = (startTime + endTime) * 0.5;
            double timeRelativeToPeak = normalizedTime - midTime;
            double radius             = midTime - startTime;
            double amplitude          = Math.Pow(1.0 / bounciness, (bounces - start));

            // Evaluate a quadratic that hits (startTime,0), (endTime, 0), and peaks at amplitude.
            return((-amplitude / (radius * radius)) * (timeRelativeToPeak - radius) * (timeRelativeToPeak + radius));
        }
        /// <summary>
        ///     Converts a DataGridLength instance to a String given the CultureInfo.
        /// </summary>
        /// <param name="gl">DataGridLength instance to convert.</param>
        /// <param name="cultureInfo">The culture to use.</param>
        /// <returns>String representation of the object.</returns>
        internal static string ConvertToString(DataGridLength length, CultureInfo cultureInfo)
        {
            switch (length.UnitType)
            {
            case DataGridLengthUnitType.Auto:
            case DataGridLengthUnitType.SizeToCells:
            case DataGridLengthUnitType.SizeToHeader:
                return(length.UnitType.ToString());

            // Star has one special case when value is "1.0" in which the value can be dropped.
            case DataGridLengthUnitType.Star:
                return(DoubleUtil.IsOne(length.Value) ? "*" : Convert.ToString(length.Value, cultureInfo) + "*");

            // Print out the numeric value. "px" can be omitted.
            default:
                return(Convert.ToString(length.Value, cultureInfo));
            }
        }
예제 #3
0
        // Token: 0x0600072A RID: 1834 RVA: 0x00016B3C File Offset: 0x00014D3C
        internal static string ToString(GridLength gl, CultureInfo cultureInfo)
        {
            GridUnitType gridUnitType = gl.GridUnitType;

            if (gridUnitType == GridUnitType.Auto)
            {
                return("Auto");
            }
            if (gridUnitType != GridUnitType.Star)
            {
                return(Convert.ToString(gl.Value, cultureInfo));
            }
            if (!DoubleUtil.IsOne(gl.Value))
            {
                return(Convert.ToString(gl.Value, cultureInfo) + "*");
            }
            return("*");
        }
        //-------------------------------------------------------------------
        //
        //  Internal Methods
        //
        //-------------------------------------------------------------------

        #region Internal Methods

        /// <summary>
        /// Converts a GridLength instance to a String given the CultureInfo.
        /// </summary>
        /// <param name="gl">GridLength instance to convert.</param>
        /// <param name="cultureInfo">Culture Info.</param>
        /// <returns>String representation of the object.</returns>
        static internal string ToString(GridLength gl, CultureInfo cultureInfo)
        {
            switch (gl.GridUnitType)
            {
            //  for Auto print out "Auto". value is always "1.0"
            case (GridUnitType.Auto):
                return("Auto");

            //  Star has one special case when value is "1.0".
            //  in this case drop value part and print only "Star"
            case (GridUnitType.Star):
                return(
                    DoubleUtil.IsOne(gl.Value)
                        ? "*"
                        : Convert.ToString(gl.Value, cultureInfo) + "*");

            //  for Pixel print out the numeric value. "px" can be omitted.
            default:
                return(Convert.ToString(gl.Value, cultureInfo));
            }
        }
        /// <summary>
        ///   Converts a RibbonControlLength instance to a String given the CultureInfo.
        /// </summary>
        internal static string ToString(RibbonControlLength length, CultureInfo cultureInfo)
        {
            switch (length.RibbonControlLengthUnitType)
            {
            //  for Auto print out "Auto". value is always "1.0"
            case RibbonControlLengthUnitType.Auto:
                return("Auto");

            case RibbonControlLengthUnitType.Item:
                return(Convert.ToString(length.Value, cultureInfo) + "items");

            //  Star has one special case when value is "1.0".
            //  in this case drop value part and print only "Star"
            case RibbonControlLengthUnitType.Star:
                return(DoubleUtil.IsOne(length.Value) ? "*" : Convert.ToString(length.Value, cultureInfo) + "*");

            //  for Pixel print out the numeric value. "px" can be omitted.
            default:
                return(Convert.ToString(length.Value, cultureInfo));
            }
        }
예제 #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="H">0---1</param>
        /// <param name="S">0---1</param>
        /// <param name="B">0---1</param>
        /// <returns></returns>
        public static Color ColorFromHsb(double H, double S, double B)
        {
            double red = 0.0, green = 0.0, blue = 0.0;

            if (DoubleUtil.IsZero(S))
            {
                red = green = blue = B;
            }
            else
            {
                var h = DoubleUtil.IsOne(H) ? 0d : (H * 6.0);
                int i = (int)Math.Floor(h);

                var f = h - i;
                var r = B * (1.0 - S);
                var s = B * (1.0 - S * f);
                var t = B * (1.0 - S * (1.0 - f));

                switch (i)
                {
                case 0: red = B; green = t; blue = r; break;

                case 1: red = s; green = B; blue = r; break;

                case 2: red = r; green = B; blue = t; break;

                case 3: red = r; green = s; blue = B; break;

                case 4: red = t; green = r; blue = B; break;

                case 5: red = B; green = r; blue = s; break;
                }
            }

            return(Color.FromRgb((byte)Math.Round(red * 255.0), (byte)Math.Round(green * 255.0), (byte)Math.Round(blue * 255.0)));
        }
예제 #7
0
        /// <summary>
        /// Content arrangement.
        /// </summary>
        /// <param name="finalSize">The final size that element should use to arrange itself and its children.</param>
        protected override sealed Size ArrangeOverride(Size finalSize)
        {
            Transform      pageTransform;
            ScaleTransform pageScaleTransform;
            Visual         pageVisual;
            Size           pageSize, pageZoom;

            CheckDisposed();

            if (_pageVisualClone == null)
            {
                if (_pageHost == null)
                {
                    _pageHost = new DocumentPageHost();
                    this.AddVisualChild(_pageHost);
                }
                Invariant.Assert(_pageHost != null);

                pageVisual = (_documentPage == null) ? null : _documentPage.Visual;
                if (pageVisual == null)
                {
                    // Remove existing visiual children.
                    _pageHost.PageVisual = null;

                    // Reset offset and transform on the page host before Arrange
                    _pageHost.CachedOffset    = new Point();
                    _pageHost.RenderTransform = null;

                    // Size for the page host needs to be set to finalSize
                    _pageHost.Arrange(new Rect(_pageHost.CachedOffset, finalSize));
                }
                else
                {
                    // Add visual representing the page contents. For performance reasons
                    // first check if it is already insered there.
                    if (_pageHost.PageVisual != pageVisual)
                    {
                        // There might be a case where a visual associated with a page was
                        // inserted to a visual tree before. It got removed later, but GC did not
                        // destroy its parent yet. To workaround this case always check for the parent
                        // of page visual and disconnect it, when necessary.
                        DocumentPageHost.DisconnectPageVisual(pageVisual);

                        _pageHost.PageVisual = pageVisual;
                    }

                    // Compute transform to be applied to the page visual. First take into account
                    // mirroring transform, if necessary. Apply also scaling transform.
                    pageSize      = _documentPage.Size;
                    pageTransform = Transform.Identity;

                    // DocumentPage.Visual is always LeftToRight, so if the current
                    // FlowDirection is RightToLeft, need to unmirror the child visual.
                    if (FlowDirection == FlowDirection.RightToLeft)
                    {
                        pageTransform = new MatrixTransform(-1.0, 0.0, 0.0, 1.0, pageSize.Width, 0.0);
                    }

                    // Apply zooming
                    if (!DoubleUtil.IsOne(_pageZoom))
                    {
                        pageScaleTransform = new ScaleTransform(_pageZoom, _pageZoom);
                        if (pageTransform == Transform.Identity)
                        {
                            pageTransform = pageScaleTransform;
                        }
                        else
                        {
                            pageTransform = new MatrixTransform(pageTransform.Value * pageScaleTransform.Value);
                        }
                        pageSize = new Size(pageSize.Width * _pageZoom, pageSize.Height * _pageZoom);
                    }

                    // Apply stretch properties
                    pageZoom = Viewbox.ComputeScaleFactor(finalSize, pageSize, this.Stretch, this.StretchDirection);
                    if (!DoubleUtil.IsOne(pageZoom.Width) || !DoubleUtil.IsOne(pageZoom.Height))
                    {
                        pageScaleTransform = new ScaleTransform(pageZoom.Width, pageZoom.Height);
                        if (pageTransform == Transform.Identity)
                        {
                            pageTransform = pageScaleTransform;
                        }
                        else
                        {
                            pageTransform = new MatrixTransform(pageTransform.Value * pageScaleTransform.Value);
                        }
                        pageSize = new Size(pageSize.Width * pageZoom.Width, pageSize.Height * pageZoom.Height);
                    }

                    // Set offset and transform on the page host before Arrange
                    _pageHost.CachedOffset    = new Point((finalSize.Width - pageSize.Width) / 2, (finalSize.Height - pageSize.Height) / 2);
                    _pageHost.RenderTransform = pageTransform;

                    // Arrange pagehost to original size of the page.
                    _pageHost.Arrange(new Rect(_pageHost.CachedOffset, _documentPage.Size));
                }

                // Fire sync notification if new page was connected.
                if (_newPageConnected)
                {
                    OnPageConnected();
                }

                // Transform for the page has been changed, need to notify TextView about the changes.
                OnTransformChangedAsync();
            }
            else
            {
                if (_pageHost.PageVisual != _pageVisualClone)
                {
                    // Remove existing visiual children.
                    _pageHost.PageVisual = _pageVisualClone;
                    // Size for the page host needs to be set to finalSize

                    // Use previous offset and transform
                    _pageHost.Arrange(new Rect(_pageHost.CachedOffset, finalSize));
                }
            }

            return(base.ArrangeOverride(finalSize));
        }
예제 #8
0
        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();
        }
예제 #9
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));
 }
예제 #10
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);
        }
 /// <summary>Arranges the content to fit a specified view size.</summary>
 /// <param name="finalSize">The maximum size that the page view should use to arrange itself and its children.</param>
 /// <returns>The actual size that the page view used to arrange itself and its children.</returns>
 // Token: 0x06005D78 RID: 23928 RVA: 0x001A4EA8 File Offset: 0x001A30A8
 protected sealed override Size ArrangeOverride(Size finalSize)
 {
     this.CheckDisposed();
     if (this._pageVisualClone == null)
     {
         if (this._pageHost == null)
         {
             this._pageHost = new DocumentPageHost();
             base.AddVisualChild(this._pageHost);
         }
         Invariant.Assert(this._pageHost != null);
         Visual visual = (this._documentPage == null) ? null : this._documentPage.Visual;
         if (visual == null)
         {
             this._pageHost.PageVisual      = null;
             this._pageHost.CachedOffset    = default(Point);
             this._pageHost.RenderTransform = null;
             this._pageHost.Arrange(new Rect(this._pageHost.CachedOffset, finalSize));
         }
         else
         {
             if (this._pageHost.PageVisual != visual)
             {
                 DocumentPageHost.DisconnectPageVisual(visual);
                 this._pageHost.PageVisual = visual;
             }
             Size      size      = this._documentPage.Size;
             Transform transform = Transform.Identity;
             if (base.FlowDirection == FlowDirection.RightToLeft)
             {
                 transform = new MatrixTransform(-1.0, 0.0, 0.0, 1.0, size.Width, 0.0);
             }
             if (!DoubleUtil.IsOne(this._pageZoom))
             {
                 ScaleTransform scaleTransform = new ScaleTransform(this._pageZoom, this._pageZoom);
                 if (transform == Transform.Identity)
                 {
                     transform = scaleTransform;
                 }
                 else
                 {
                     transform = new MatrixTransform(transform.Value * scaleTransform.Value);
                 }
                 size = new Size(size.Width * this._pageZoom, size.Height * this._pageZoom);
             }
             Size size2 = Viewbox.ComputeScaleFactor(finalSize, size, this.Stretch, this.StretchDirection);
             if (!DoubleUtil.IsOne(size2.Width) || !DoubleUtil.IsOne(size2.Height))
             {
                 ScaleTransform scaleTransform = new ScaleTransform(size2.Width, size2.Height);
                 if (transform == Transform.Identity)
                 {
                     transform = scaleTransform;
                 }
                 else
                 {
                     transform = new MatrixTransform(transform.Value * scaleTransform.Value);
                 }
                 size = new Size(size.Width * size2.Width, size.Height * size2.Height);
             }
             this._pageHost.CachedOffset    = new Point((finalSize.Width - size.Width) / 2.0, (finalSize.Height - size.Height) / 2.0);
             this._pageHost.RenderTransform = transform;
             this._pageHost.Arrange(new Rect(this._pageHost.CachedOffset, this._documentPage.Size));
         }
         if (this._newPageConnected)
         {
             this.OnPageConnected();
         }
         this.OnTransformChangedAsync();
     }
     else if (this._pageHost.PageVisual != this._pageVisualClone)
     {
         this._pageHost.PageVisual = this._pageVisualClone;
         this._pageHost.Arrange(new Rect(this._pageHost.CachedOffset, finalSize));
     }
     return(base.ArrangeOverride(finalSize));
 }
예제 #12
0
        protected override bool TryCalculate(Dictionary <DateTime, double> history, DateTime now, int barNum, object[] args, out double val)
        {
            int    col      = 0;
            double price    = (double)args[col++];
            double rawDelta = (double)args[col++];
            //IOptionSeries optSer = (IOptionSeries)args[col++];
            double   priceStep        = (double)args[col++];
            DateTime expirationDate   = (DateTime)args[col++];
            string   underlyingSymbol = (string)args[col++];
            DateTime lastUpdate       = (DateTime)args[col++];
            var      baseSecDesc      = (DataSource.IDataSourceSecurity)args[col++];
            bool     permissionToWork = (bool)args[col++];
            // Здесь работаем не с парами, а со списком, чтобы потом было легче обобщить на весь опцион целиком.
            var strikes = (IEnumerable <IOptionStrike>)args[col++];
            // Шаг лотности БАЗОВОГО АКТИВА (нужен для Дерибит в первую очередь)
            double lotTick = (double)args[col++];

            val = rawDelta;

            #region Validate args
            double futPx = price;
            // Входные параметры не проинициализированы
            if (Double.IsNaN(rawDelta) || (!DoubleUtil.IsPositive(futPx)))
            {
                return(true);
            }

            // Входные параметры не проинициализированы
            //if ((optSer == null) || (optSer.UnderlyingAsset == null) || (optSer.UnderlyingAsset.SecurityDescription == null))
            //    return true;
            if (!DoubleUtil.IsPositive(priceStep))
            {
                return(true);
            }

            if (!DoubleUtil.IsPositive(lotTick))
            {
                return(true);
            }

            m_buyPrice.Value  = futPx + m_buyShift * priceStep;
            m_sellPrice.Value = futPx + m_sellShift * priceStep;

            // PROD-3687: Если выйти из метода слишком рано, то не будут заполнены контролы на UI
            if (!m_hedgeDelta)
            {
                return(true);
            }

            if (!permissionToWork)
            {
                // PROD-4568 - Если параметр блока говорит "можно", а на вход блока из скрипта подан запрет,
                // то нужно записать в лог значения этих параметров, чтобы не было вопросов потом.
                // См. также обсуждение на форуме: http://forum.tslab.ru/ubb/ubbthreads.php?ubb=showflat&Number=80364#Post80364

                if (Context.Runtime.IsAgentMode)
                {
                    string tName  = (Context.Runtime.TradeName ?? "").Replace(Constants.HtmlDot, ".");
                    string expiry = expirationDate.ToString(DateTimeFormatWithMs, CultureInfo.InvariantCulture);
                    string msg    = String.Format("[{0}.{1}] Execution is blocked. Symbol:{2}; Expiry:{3};   HedgeDelta:{4}; Permission:{5}",
                                                  MsgId, tName, underlyingSymbol, expiry, m_hedgeDelta, permissionToWork);
                    m_context.Log(msg, MessageType.Warning, false);
                }

                return(true);
            }

            DateTime lastExec = LastExecution;
            //DateTime lastUpdate = optSer.UnderlyingAsset.FinInfo.LastUpdate;
            // В некоторых случаях слишком частое исполнение нам не подходит
            if ((lastUpdate - lastExec).TotalSeconds < m_minPeriod)
            {
                // Но надо проверять изменения в составе портфеля, чтобы вовремя ровнять дельту
                // НО КАК???
                return(true);
            }
            #endregion Validate args

            // Если дельта уже лежит в заданных границах - просто выходим
            double dnEdge = m_targetDelta.Value - Math.Abs(m_doDelta.Value) + (1.0 - m_sensitivity);
            double upEdge = m_targetDelta.Value + Math.Abs(m_upDelta.Value) - (1.0 - m_sensitivity);
            // Пересчитываем пороги срабатывания в истинные лоты
            dnEdge *= lotTick;
            upEdge *= lotTick;
            if ((dnEdge < rawDelta) && (rawDelta < upEdge))
            {
                //string msg = String.Format(CultureInfo.InvariantCulture, "[{0}] Delta is too low to hedge. Delta: {1}; TargetDelta: {2}; Sensitivity: {3}",
                //  MsgId, rawDelta, m_targetDelta.Value, m_sensitivity);
                //context.Log(msg, logColor, true);

                return(true);
            }

            //var baseSecDesc = optSer.UnderlyingAsset.SecurityDescription;
            PositionsManager posMan = PositionsManager.GetManager(m_context);
            ISecurity        sec    = (from s in m_context.Runtime.Securities
                                       where (s.SecurityDescription != null) && baseSecDesc.Equals(s.SecurityDescription)
                                       select s).SingleOrDefault();
            if (sec == null)
            {
                string msg = String.Format("[{0}] There is no security. Symbol: {1}", MsgId, underlyingSymbol);
                m_context.Log(msg, MessageType.Warning, true);
                return(true);
            }

            // PROD-6000 - Если в позиции вообще нет опционов, значит произошла какая-то ошибка
            if (!m_workWithoutOptions)
            {
                bool hasAnyOption = HasAnyOptionPosition(posMan, strikes);
                if (!hasAnyOption)
                {
                    // В режиме агента обязательно логгируем, чтобы потом вопросов не было
                    if (Context.Runtime.IsAgentMode)
                    {
                        string tName  = (Context.Runtime.TradeName ?? "").Replace(Constants.HtmlDot, ".");
                        string expiry = expirationDate.ToString(DateTimeFormatWithMs, CultureInfo.InvariantCulture);
                        string msg    = String.Format("[{0}.{1}] Execution is blocked. Symbol:{2}; Expiry:{3};   WorkWithoutOptions:{4}; HasAnyOption:{5}",
                                                      MsgId, tName, underlyingSymbol, expiry, m_workWithoutOptions, hasAnyOption);
                        m_context.Log(msg, MessageType.Warning, false);
                    }

                    return(true);
                }
            }

            // Здесь rawDelta и dnEdge ОБА в истинных лотах
            if (rawDelta <= dnEdge)
            {
                double diffLots = m_targetDelta.Value * lotTick - rawDelta;
                // Переводим в штуки LotTick-ов
                double diffLotTicks = diffLots / lotTick;

                int roundedLo = Math.Sign(diffLotTicks) * (int)Math.Floor(Math.Abs(diffLotTicks));
                int roundedHi = Math.Sign(diffLotTicks) * (1 + (int)Math.Floor(Math.Abs(diffLotTicks)));
                int rounded;
                //if (Math.Abs(rawDelta + roundedLo - m_targetDelta.Value) <= Math.Abs(rawDelta + roundedHi - m_targetDelta.Value))
                if (Math.Abs(roundedLo - diffLotTicks) <= Math.Abs(roundedHi - diffLotTicks))
                {
                    rounded = roundedLo;
                }
                else
                {
                    rounded = roundedHi;
                }

                if (rounded > 0)
                {
                    // [2015-07-15] Сдвиг заявки хеджа относительно рынка на заданную величину
                    double px = futPx + m_buyShift * sec.Tick;

                    string signalName;
                    if (DoubleUtil.IsOne(lotTick))
                    {
                        signalName = String.Format(CultureInfo.InvariantCulture, "F:{0}; Delta:{1}; TargetDelta:{2}",
                                                   px, rawDelta, m_targetDelta.Value);
                    }
                    else
                    {
                        signalName = String.Format(CultureInfo.InvariantCulture, "F:{0}; Delta:{1}; TargetDelta:{2}; LotTick:{3}",
                                                   px, rawDelta, m_targetDelta.Value * lotTick, lotTick);
                    }
                    m_context.Log(signalName, MessageType.Warning, false);
                    posMan.BuyAtPrice(m_context, sec, Math.Abs(rounded * lotTick), px, "Delta BUY", signalName);

                    m_context.StoreObject(VariableId + "_" + LastExecutionKey, now);
                }
            }
            // Здесь upEdge и rawDelta ОБА в истинных лотах
            else if (upEdge <= rawDelta)
            {
                double diffLots = m_targetDelta.Value * lotTick - rawDelta; // в этой ветке diff обычно отрицательный...
                // Переводим в штуки LotTick-ов
                double diffLotTicks = diffLots / lotTick;

                int roundedLo = Math.Sign(diffLotTicks) * (int)Math.Floor(Math.Abs(diffLotTicks));
                int roundedHi = Math.Sign(diffLotTicks) * (1 + (int)Math.Floor(Math.Abs(diffLotTicks)));
                int rounded;
                if (Math.Abs(roundedLo - diffLotTicks) <= Math.Abs(roundedHi - diffLotTicks))
                {
                    rounded = roundedLo;
                }
                else
                {
                    rounded = roundedHi;
                }

                if (rounded < 0)
                {
                    // [2015-07-15] Сдвиг заявки хеджа относительно рынка на заданную величину
                    double px = futPx + m_sellShift * sec.Tick;

                    string signalName;
                    if (DoubleUtil.IsOne(lotTick))
                    {
                        signalName = String.Format(CultureInfo.InvariantCulture, "F:{0}; Delta:{1}; TargetDelta:{2}",
                                                   px, rawDelta, m_targetDelta.Value);
                    }
                    else
                    {
                        signalName = String.Format(CultureInfo.InvariantCulture, "F:{0}; Delta:{1}; TargetDelta:{2}; LotTick:{3}",
                                                   px, rawDelta, m_targetDelta.Value * lotTick, lotTick);
                    }
                    m_context.Log(signalName, MessageType.Warning, false);
                    posMan.SellAtPrice(m_context, sec, Math.Abs(rounded * lotTick), px, "Delta SELL", signalName);

                    m_context.StoreObject(VariableId + "_" + LastExecutionKey, now);
                }
            }

            return(true);
        }