Example #1
0
        /// <summary>
        /// Тета опционной пары по формуле Блека-Шолза
        /// </summary>
        internal static void GetPairTheta(PositionsManager posMan, InteractiveSeries smile, IOptionStrikePair pair,
                                          double f, double dT, out double totalTheta)
        {
            totalTheta = 0;

            ISecurity putSec = pair.Put.Security, callSec = pair.Call.Security;
            // закрытые позы не дают в клада в тету, поэтому беру только активные
            ReadOnlyCollection <IPosition> putPositions  = posMan.GetActiveForBar(putSec);
            ReadOnlyCollection <IPosition> callPositions = posMan.GetActiveForBar(callSec);

            if ((putPositions.Count <= 0) && (callPositions.Count <= 0))
            {
                return;
            }

            double?sigma = null;

            if ((smile.Tag != null) && (smile.Tag is SmileInfo))
            {
                double    tmp;
                SmileInfo info = smile.GetTag <SmileInfo>();
                if (info.ContinuousFunction.TryGetValue(pair.Strike, out tmp))
                {
                    sigma = tmp;
                }
            }

            if (sigma == null)
            {
                sigma = (from d2 in smile.ControlPoints
                         let point = d2.Anchor.Value
                                     where (DoubleUtil.AreClose(pair.Strike, point.X))
                                     select(double?) point.Y).FirstOrDefault();
            }

            if (sigma == null)
            {
                return;
            }

            {
                double putTheta;
                GetOptTheta(putPositions,
                            f, pair.Strike, dT, sigma.Value, 0.0, false, out putTheta);
                totalTheta += putTheta;
            }

            {
                double callTheta;
                GetOptTheta(callPositions,
                            f, pair.Strike, dT, sigma.Value, 0.0, true, out callTheta);
                totalTheta += callTheta;
            }
        }
        internal static void GetBaseDelta(PositionsManager posMan, ISecurity sec, int barNum, double f, out double rawDelta)
        {
            rawDelta = 0;

            // дельта БА всегда 1?
            const double Delta = 1;

            // закрытые позы не дают в клада в дельту, поэтому беру только активные
            var positions = posMan.GetActiveForBar(sec);

            foreach (IPosition pos in positions)
            {
                //if (pos.EntrySignalName.StartsWith("CHT-RI-03.", StringComparison.InvariantCultureIgnoreCase))
                //{
                //    string str = "";
                //}

                // Пока что State лучше не трогать
                //if (pos.PositionState == PositionState.HaveError)
                {
                    int    sign = pos.IsLong ? 1 : -1;
                    double qty  = Math.Abs(pos.Shares);
                    rawDelta += sign * qty * Delta;
                }
            }
        }
        public static void GetPairQty(PositionsManager posMan, IOptionStrikePair pair, out double putQty, out double callQty)
        {
            putQty  = 0;
            callQty = 0;

            ISecurity putSec = pair.Put.Security, callSec = pair.Call.Security;
            ReadOnlyCollection <IPosition> putPositions = posMan.GetActiveForBar(putSec);
            ReadOnlyCollection <IPosition> callPositions = posMan.GetActiveForBar(callSec);

            if ((putPositions.Count <= 0) && (callPositions.Count <= 0))
            {
                return;
            }

            GetTotalQty(putPositions, out putQty);
            GetTotalQty(callPositions, out callQty);
        }
Example #4
0
        /// <summary>
        /// Полный суммарный открытый объём в данном инструменте в позициях указанного направления
        /// (запасной вариант подсчета. По идее, должен быть синхронизирован с таким же методом в классе PositionsManager)
        /// </summary>
        /// <param name="sec">инструмент</param>
        /// <param name="barNum">индекс бара</param>
        /// <returns>суммарный объём (в лотах)</returns>
        public double GetTotalQty(ISecurity sec, int barNum)
        {
            double res       = 0;
            var    positions = PositionsManager.GetActiveForBar(sec, barNum, TotalProfitAlgo.AllPositions, null);

            for (int j = 0; j < positions.Count; j++)
            {
                IPosition pos  = positions[j];
                int       sign = pos.IsLong ? 1 : -1;
                double    qty  = Math.Abs(pos.Shares);
                res += sign * qty;
            }
            return(res);
        }
        internal static void GetBaseDelta(PositionsManager posMan, ISecurity sec, int barNum, double f, out double rawDelta)
        {
            rawDelta = 0;

            // дельта БА всегда 1?
            const double Delta = 1;

            // закрытые позы не дают в клада в дельту, поэтому беру только активные
            var positions = posMan.GetActiveForBar(sec);

            foreach (IPosition pos in positions)
            {
                // Пока что State лучше не трогать
                //if (pos.PositionState == PositionState.HaveError)
                {
                    int    sign = pos.IsLong ? 1 : -1;
                    double qty  = Math.Abs(pos.Shares);
                    rawDelta += sign * qty * Delta;
                }
            }
        }
Example #6
0
        public InteractiveSeries Execute(IOptionSeries optSer, int barNum)
        {
            int barsCount = ContextBarsCount;

            if ((barNum < barsCount - 1) || (optSer == null))
            {
                return(Constants.EmptySeries);
            }

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

            IOptionStrike[]  options = optSer.GetStrikes().ToArray();
            PositionsManager posMan  = PositionsManager.GetManager(m_context);

            //if (Context.Runtime.IsAgentMode)
            //{
            // PROD-6089 - Если мы в режиме агента, значит все инструменты уже ISecurityRt
            //    SortedList<DateTime, IOrder> sortedOrders = new SortedList<DateTime, IOrder>(s_comparer);
            //}

            SortedList <DateTime, IPosition> sortedPos = new SortedList <DateTime, IPosition>(s_comparer);

            if (m_countFutures)
            {
                ReadOnlyCollection <IPosition> futPositions = posMan.GetActiveForBar(optSer.UnderlyingAsset);
                if (futPositions.Count > 0)
                {
                    for (int j = 0; j < futPositions.Count; j++)
                    {
                        IPosition pos = futPositions[j];
                        AddSafely(sortedPos, pos);
                    }
                }
            }

            for (int m = 0; m < options.Length; m++)
            {
                IOptionStrike optStrike = options[m];
                ReadOnlyCollection <IPosition> optPositions = posMan.GetActiveForBar(optStrike.Security);
                if (optPositions.Count > 0)
                {
                    for (int j = 0; j < optPositions.Count; j++)
                    {
                        IPosition pos = optPositions[j];
                        AddSafely(sortedPos, pos);
                    }
                }
            }

            int counter = 0;
            List <InteractiveObject> controlPoints = new List <InteractiveObject>();

            foreach (var node in sortedPos)
            {
                InteractivePointActive ip = new InteractivePointActive();
                ip.IsActive = true;
                //ip.DragableMode = DragableMode.None;
                ip.DateTime = node.Key;
                ip.ValueX   = 0; // все одинаковые 'страйки' имеют
                ip.ValueY   = PrepareValue(node, barNum, m_displayMode);
                ip.Tooltip  = PrepareTooltip(node, barNum, m_displayMode);

                controlPoints.Add(new InteractiveObject(ip));

                counter++;
                if (counter >= m_maxPositions)
                {
                    break;
                }
            }

            InteractiveSeries res = new InteractiveSeries(); // Здесь правильно делать new

            // Задаю свойство для отображения
            switch (m_displayMode)
            {
            case PositionGridDisplayMode.Px:
            case PositionGridDisplayMode.Qty:
                res.DisplayProperty.Name = nameof(IInteractivePointLight.ValueY);
                break;

            default:
                res.DisplayProperty.Name = nameof(InteractivePointActive.Tooltip);
                break;
            }
            res.ControlPoints = new ReadOnlyCollection <InteractiveObject>(controlPoints);

            SetHandlerInitialized(now);

            return(res);
        }
        public InteractiveSeries Execute(double time, InteractiveSeries smile, IOptionSeries optSer, int barNum)
        {
            int barsCount = ContextBarsCount;

            if ((barNum < barsCount - 1) || (optSer == null))
            {
                return(Constants.EmptySeries);
            }

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

            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, true);
                }
                return(Constants.EmptySeries);
            }

            if (smile == null)
            {
                string msg = String.Format("[{0}] Argument 'smile' must be filled with InteractiveSeries.", GetType().Name);
                if (wasInitialized)
                {
                    m_context.Log(msg, MessageType.Error, true);
                }
                return(Constants.EmptySeries);
            }

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

            if (oldInfo == null)
            {
                string msg = String.Format("[{0}] Property Tag of object smile must be filled with SmileInfo. Tag:{1}", GetType().Name, smile.Tag);
                if (wasInitialized)
                {
                    m_context.Log(msg, MessageType.Error, false);
                }
                return(Constants.EmptySeries);
            }

            double futPx;

            if (DoubleUtil.IsPositive(oldInfo.F))
            {
                futPx = oldInfo.F;
            }
            else
            {
                futPx = optSer.UnderlyingAsset.Bars[Math.Min(barNum, lastBarIndex)].Close;
            }

            IOptionStrikePair[]      pairs         = optSer.GetStrikePairs().ToArray();
            PositionsManager         posMan        = PositionsManager.GetManager(m_context);
            List <InteractiveObject> controlPoints = new List <InteractiveObject>();

            if (m_countFutures)
            {
                ReadOnlyCollection <IPosition> futPositions = posMan.GetActiveForBar(optSer.UnderlyingAsset);
                if (futPositions.Count > 0)
                {
                    double futQty;
                    GetTotalQty(futPositions, out futQty);

                    if (!DoubleUtil.IsZero(futQty))
                    {
                        // ReSharper disable once UseObjectOrCollectionInitializer
                        InteractivePointActive ip = new InteractivePointActive(0, futQty);
                        ip.IsActive = true;
                        //ip.DragableMode = DragableMode.None;
                        //ip.Geometry = Geometries.Rect;
                        //ip.Color = Colors.DarkOrange;

                        //// PROD-1194 - Цвет ячеек и фона
                        //if (futQty > 0)
                        //    ip.BackColor = ScriptColors.Aquamarine;
                        //else if (futQty < 0)
                        //    ip.BackColor = ScriptColors.LightSalmon;
                        //if (ip.BackColor != null)
                        //    ip.ForeColor = ScriptColors.Black;

                        // TODO: Ждем решения PROD-6009
                        //// PROD-1194 - Цвет ячеек и фона -- фон красится по принципу "в деньгах или нет", шрифт -- по знаку
                        //if (futQty > 0)
                        //    ip.ForeColor = ScriptColors.LightGreen;
                        //else if (futQty < 0)
                        //    ip.ForeColor = ScriptColors.Red;
                        ////if () // Фьючерс не красится!
                        ////    ip.ForeColor = ScriptColors.Black;

                        ip.Tooltip = String.Format(CultureInfo.InvariantCulture, "Fut Qty:{0}", futQty);

                        controlPoints.Add(new InteractiveObject(ip));
                    }
                }
            }

            for (int j = 0; j < pairs.Length; j++)
            {
                IOptionStrikePair pair = pairs[j];
                double            putQty, callQty;
                GetPairQty(posMan, pair, out putQty, out callQty);

                if ((!DoubleUtil.IsZero(putQty)) || (!DoubleUtil.IsZero(callQty)))
                {
                    double y       = 0;
                    Color? backCol = null;
                    switch (m_optionType)
                    {
                    case StrikeType.Put:
                        y       = putQty;
                        backCol = (pair.Strike > futPx) ? ScriptColors.LightCyan : ScriptColors.LightYellow;
                        break;

                    case StrikeType.Call:
                        y       = callQty;
                        backCol = (pair.Strike < futPx) ? ScriptColors.LightCyan : ScriptColors.LightYellow;
                        break;

                    case StrikeType.Any:
                        y = putQty + callQty;
                        break;

                    default:
                        throw new NotImplementedException("OptionType: " + m_optionType);
                    }

                    if (
                        (!DoubleUtil.IsZero(y)) ||
                        ((m_optionType == StrikeType.Any) && ((!DoubleUtil.IsZero(putQty)) || (!DoubleUtil.IsZero(callQty))))) // Хотя вообще-то мы внутри if и второй блок проверок всегда true...
                    {
                        // ReSharper disable once UseObjectOrCollectionInitializer
                        InteractivePointActive ip = new InteractivePointActive(pair.Strike, y);
                        ip.IsActive = true;
                        //ip.DragableMode = DragableMode.None;
                        //ip.Geometry = Geometries.Rect;
                        //ip.Color = Colors.DarkOrange;

                        //// PROD-1194 - Цвет ячеек и фона
                        //if (y > 0)
                        //    ip.BackColor = ScriptColors.Aquamarine;
                        //else if (y < 0)
                        //    ip.BackColor = ScriptColors.LightSalmon;
                        //if (ip.BackColor != null)
                        //    ip.ForeColor = ScriptColors.Black;

                        // TODO: Ждем решения PROD-6009
                        //// PROD-1194 - Цвет ячеек и фона -- фон красится по принципу "в деньгах или нет", шрифт -- по знаку
                        //if (y > 0)
                        //    ip.ForeColor = ScriptColors.LightGreen;
                        //else if (y < 0)
                        //    ip.ForeColor = ScriptColors.Red;
                        ////if (backCol != null)
                        ////    ip.BackColor = backCol;

                        ip.Tooltip = String.Format(CultureInfo.InvariantCulture, "K:{0}; Qty:{1}", pair.Strike, y);

                        controlPoints.Add(new InteractiveObject(ip));
                    }
                }
            }

            // ReSharper disable once UseObjectOrCollectionInitializer
            InteractiveSeries res = new InteractiveSeries(); // Здесь правильно делать new

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

            SetHandlerInitialized(now);

            return(res);
        }