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