internal static bool TryEstimateGamma(PositionsManager posMan, IOptionSeries optSer, IOptionStrikePair[] pairs,
                                              InteractiveSeries smile, NumericalGreekAlgo greekAlgo,
                                              double f, double dF, double timeToExpiry, out double rawGamma)
        {
            rawGamma = Double.NaN;

            if (timeToExpiry < Double.Epsilon)
            {
                throw new ArgumentOutOfRangeException("timeToExpiry", "timeToExpiry must be above zero. timeToExpiry:" + timeToExpiry);
            }

            double delta1, delta2;
            bool   ok1 = SingleSeriesNumericalDelta.TryEstimateDelta(posMan, optSer, pairs, smile, greekAlgo,
                                                                     f - dF, dF, timeToExpiry, out delta1);

            if (!ok1)
            {
                return(false);
            }

            bool ok2 = SingleSeriesNumericalDelta.TryEstimateDelta(posMan, optSer, pairs, smile, greekAlgo,
                                                                   f + dF, dF, timeToExpiry, out delta2);

            if (!ok2)
            {
                return(false);
            }

            rawGamma = (delta2 - delta1) / 2.0 / dF;
            return(true);
        }
Ejemplo n.º 2
0
        public double Execute(double price, double time, InteractiveSeries smile, IOptionSeries optSer, int barNum)
        {
            int barsCount = m_context.BarsCount;

            if (!m_context.IsLastBarUsed)
            {
                barsCount--;
            }
            if ((barNum < barsCount - 1) || (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, 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);
            }

            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.NaN);
            }

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

            double rawDelta, res;
            double dF = optSer.UnderlyingAsset.Tick;

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

            if (SingleSeriesNumericalDelta.TryEstimateDelta(posMan, optSer, pairs, smile, m_greekAlgo, f, dF, dT, out rawDelta))
            {
                res = rawDelta;
            }
            else
            {
                res = Constants.NaN;
            }

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

            if ((sInfo != null) && (sInfo.ContinuousFunction != null))
            {
                double iv  = sInfo.ContinuousFunction.Value(sInfo.F);
                string msg = String.Format("[{0}] F:{1}; dT:{2};   smile.F:{3}; smile.dT:{4}; smile.IV:{5}",
                                           GetType().Name, f, dT, sInfo.F, sInfo.dT, iv);
                m_context.Log(msg, MessageType.Info, false);
            }

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

            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
                    {
                        int       len = optSer.UnderlyingAsset.Bars.Count;
                        ISecurity sec = (from s in m_context.Runtime.Securities
                                         where (s.SecurityDescription.Equals(optSer.UnderlyingAsset.SecurityDescription))
                                         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)
                            {
                                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)
                            {
                                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(res);
        }
Ejemplo n.º 3
0
        public IList <double> Execute(IList <double> prices, IList <double> times, InteractiveSeries smile, IOptionSeries optSer)
        {
            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 = optSer.UnderlyingAsset.Bars.Count;

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

            double f  = prices[prices.Count - 1];
            double dT = times[times.Count - 1];

            if ((dT < Double.Epsilon) || Double.IsNaN(dT) || Double.IsNaN(f))
            {
                return(positionDeltas);
            }

            double rawDelta, res;
            double dF = optSer.UnderlyingAsset.Tick;

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

            if (SingleSeriesNumericalDelta.TryEstimateDelta(posMan, optSer, pairs, smile, m_greekAlgo, f, dF, dT, out rawDelta))
            {
                res = rawDelta;
            }
            else
            {
                res = Constants.NaN;
            }

            positionDeltas[positionDeltas.Count - 1] = res;

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

            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
                    {
                        ISecurity sec = (from s in m_context.Runtime.Securities
                                         where (s.SecurityDescription.Equals(optSer.UnderlyingAsset.SecurityDescription))
                                         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)
                            {
                                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)
                            {
                                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
            }

            return(positionDeltas);
        }