internal static void FillNodeInfoDeribit(InteractivePointActive ip, double f, double dT, IOptionStrikePair sInfo, StrikeType optionType, OptionPxMode optPxMode, double optPx, double optQty, double optSigma, DateTime optTime, bool returnPct, double riskfreeRatePct, double scaleMult) { // Вызов базовой реализации FillNodeInfo(ip, f, dT, sInfo, optionType, optPxMode, optPx, optQty, optSigma, optTime, returnPct, riskfreeRatePct); // Заменяю тултип, чтобы в нем были и биткойны и доллары var opTypeStr = String.Intern(optionType.ToString()); var opTypeSpace = String.Intern(new string(' ', opTypeStr.Length)); // Пробелы по виду занимают меньше места, чем буквы, поэтому чуть-чуть подравниваю? opTypeSpace += " "; if (optQty > 0) { ip.Tooltip = String.Format(CultureInfo.InvariantCulture, " K:{0}; IV:{1:###0.00}%\r\n" + " {2} px(B) {3:##0.0000} qty {4}\r\n" + " {5} px($) {6:######0.00} qty {4}", sInfo.Strike, optSigma * Constants.PctMult, opTypeStr, optPx, optQty, opTypeSpace, optPx * scaleMult); } else { ip.Tooltip = String.Format(CultureInfo.InvariantCulture, " K:{0}; IV:{1:###0.00}%\r\n" + " {2} px(B) {3:##0.0000}\r\n" + " {4} px($) {5:######0.00}", sInfo.Strike, optSigma * Constants.PctMult, opTypeStr, optPx, opTypeSpace, optPx * scaleMult); } }
internal static void FillNodeInfo(InteractivePointActive ip, double f, double dT, IOptionStrikePair sInfo, StrikeType optionType, OptionPxMode optPxMode, double optSigma, bool returnPct, bool isVisiblePoints, double scaleMult, double riskfreeRatePct) { if (optionType == StrikeType.Any) { throw new ArgumentException("Option type 'Any' is not supported.", "optionType"); } bool isCall = (optionType == StrikeType.Call); double optPx = FinMath.GetOptionPrice(f, sInfo.Strike, dT, optSigma, 0, isCall); // Сразу переводим котировку из баксов в битки optPx /= scaleMult; // ReSharper disable once UseObjectOrCollectionInitializer SmileNodeInfo nodeInfo = new SmileNodeInfo(); nodeInfo.F = f; nodeInfo.dT = dT; nodeInfo.RiskFreeRate = riskfreeRatePct; nodeInfo.Sigma = returnPct ? optSigma * Constants.PctMult : optSigma; nodeInfo.OptPx = optPx; nodeInfo.Strike = sInfo.Strike; // Сюда мы приходим когда хотим торговать, поэтому обращение к Security уместно nodeInfo.Security = (optionType == StrikeType.Put) ? sInfo.Put.Security : sInfo.Call.Security; nodeInfo.PxMode = optPxMode; nodeInfo.OptionType = optionType; nodeInfo.Pair = sInfo; //nodeInfo.ScriptTime = optTime; nodeInfo.CalendarTime = DateTime.Now; nodeInfo.Symbol = nodeInfo.Security.Symbol; nodeInfo.DSName = nodeInfo.Security.SecurityDescription.DSName; nodeInfo.Expired = nodeInfo.Security.SecurityDescription.Expired; nodeInfo.FullName = nodeInfo.Security.SecurityDescription.FullName; ip.Tag = nodeInfo; //ip.Color = Colors.Yellow; ip.IsActive = isVisiblePoints; ip.Geometry = Geometries.Ellipse; ip.DragableMode = DragableMode.None; //ip.Value = new System.Windows.Point(sInfo.Strike, nodeInfo.Sigma); // Поскольку цены скорее всего расчетные, показываю на 1 знак болььше, чем объявлена точность в инструменте int decim = Math.Max(0, nodeInfo.Security.Decimals + 1); string optPxStr = optPx.ToString("N" + decim, CultureInfo.InvariantCulture); ip.Tooltip = String.Format(CultureInfo.InvariantCulture, " K: {0}; IV: {1:#0.00}%\r\n {2} px {3}", sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx); }
private void InteractiveSplineOnClickEvent(object sender, InteractiveActionEventArgs eventArgs) { OptionPxMode pxMode = m_isLong ? OptionPxMode.Ask : OptionPxMode.Bid; PositionsManager posMan = PositionsManager.GetManager(m_context); // Из практики торговли часто бывает ситуация, что торговля заблокирована, а снять задачу котирования УЖЕ хочется. //if (posMan.BlockTrading) //{ // //string msg = String.Format("[{0}] Trading is blocked. Please, change 'Block Trading' parameter.", m_optionPxMode); // string msg = String.Format(RM.GetString("OptHandlerMsg.PositionsManager.TradingBlocked"), pxMode); // m_context.Log(msg, MessageType.Info, true); // return; //} InteractivePointActive tmp = eventArgs.Point; if ((tmp.Tag == null) || (!(tmp.Tag is PositionsManager.IvTargetInfo))) { string msg = String.Format("[{0}.ClickEvent] Denied #1", GetType().Name); m_context.Log(msg, MessageType.Warning, false); return; } { string msg = String.Format(CultureInfo.InvariantCulture, "[{0}.ClickEvent] Strike: {1}", GetType().Name, eventArgs.Point.ValueX); m_context.Log(msg, MessageType.Warning, false); } var ivTarget = tmp.Tag as PositionsManager.IvTargetInfo; // Передаю событие в PositionsManager //posMan.InteractiveSplineOnQuoteIvEvent(m_context, sender, eventArgs); // ОЧЕНЬ БОЛЬШОЙ ВОПРОС ЧТО БУДЕТ С КОНТЕКСТОМ ПРИ ЭТОМ??? int res = posMan.CancelVolatility(m_context, ivTarget, "Left-click"); if (res > 0) { string msg = String.Format(RM.GetString("OptHandlerMsg.PositionsManager.IvTargetCancelled"), pxMode, ivTarget); m_context.Log(msg, MessageType.Info, true, new Dictionary <string, object> { { "VOLATILITY_ORDER_CANCELLED", msg } }); // Вызываем принудительный пересчет агента, чтобы немедленно убрать заявку из стакана m_context.Recalc(); } }
internal static void FillNodeInfo(InteractivePointActive ip, double f, double dT, IOptionStrikePair sInfo, StrikeType optionType, OptionPxMode optPxMode, double optSigma, bool returnPct, bool isVisiblePoints, double riskfreeRatePct) { if (optionType == StrikeType.Any) { throw new ArgumentException("Option type 'Any' is not supported.", "optionType"); } bool isCall = (optionType == StrikeType.Call); double optPx = FinMath.GetOptionPrice(f, sInfo.Strike, dT, optSigma, 0, isCall); // ReSharper disable once UseObjectOrCollectionInitializer SmileNodeInfo nodeInfo = new SmileNodeInfo(); nodeInfo.F = f; nodeInfo.dT = dT; nodeInfo.RiskFreeRate = riskfreeRatePct; nodeInfo.Sigma = returnPct ? optSigma * Constants.PctMult : optSigma; nodeInfo.OptPx = optPx; nodeInfo.Strike = sInfo.Strike; // Сюда мы приходим когда хотим торговать, поэтому обращение к Security уместно nodeInfo.Security = (optionType == StrikeType.Put) ? sInfo.Put.Security : sInfo.Call.Security; nodeInfo.PxMode = optPxMode; nodeInfo.OptionType = optionType; nodeInfo.Pair = sInfo; //nodeInfo.ScriptTime = optTime; nodeInfo.CalendarTime = DateTime.Now; nodeInfo.Symbol = nodeInfo.Security.Symbol; nodeInfo.DSName = nodeInfo.Security.SecurityDescription.DSName; nodeInfo.Expired = nodeInfo.Security.SecurityDescription.Expired; nodeInfo.FullName = nodeInfo.Security.SecurityDescription.FullName; ip.Tag = nodeInfo; ip.Color = AlphaColors.Yellow; ip.IsActive = isVisiblePoints; ip.Geometry = Geometries.Ellipse; ip.DragableMode = DragableMode.None; //ip.Value = new System.Windows.Point(sInfo.Strike, nodeInfo.Sigma); ip.Tooltip = String.Format(CultureInfo.InvariantCulture, "F:{0}; K:{1}; IV:{2:#0.00}%\r\n{3} px {4}", f, sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx); }
protected static void FillNodeInfo(InteractivePointLight ip, double f, double dT, IOptionStrikePair sInfo, StrikeType optionType, OptionPxMode optPxMode, double optSigma, bool returnPct, double pctRate) { if (optionType == StrikeType.Any) { throw new ArgumentException("Option type 'Any' is not supported.", "optionType"); } bool isCall = (optionType == StrikeType.Call); double optPx = FinMath.GetOptionPrice(f, sInfo.Strike, dT, optSigma, pctRate, isCall); // ReSharper disable once UseObjectOrCollectionInitializer SmileNodeInfo nodeInfo = new SmileNodeInfo(); nodeInfo.F = f; nodeInfo.dT = dT; nodeInfo.RiskFreeRate = pctRate; nodeInfo.Sigma = returnPct ? optSigma * Constants.PctMult : optSigma; nodeInfo.OptPx = optPx; nodeInfo.Strike = sInfo.Strike; nodeInfo.Security = (optionType == StrikeType.Put) ? sInfo.Put.Security : sInfo.Call.Security; nodeInfo.PxMode = optPxMode; nodeInfo.OptionType = optionType; nodeInfo.Pair = sInfo; //nodeInfo.ScriptTime = optTime; nodeInfo.CalendarTime = DateTime.Now; nodeInfo.Symbol = nodeInfo.Security.Symbol; nodeInfo.DSName = nodeInfo.Security.SecurityDescription.DSName; nodeInfo.FullName = nodeInfo.Security.SecurityDescription.FullName; nodeInfo.Expired = nodeInfo.Security.SecurityDescription.Expired; ip.Tag = nodeInfo; ip.Value = new Point(sInfo.Strike, nodeInfo.Sigma); if (ip is InteractivePointActive) { InteractivePointActive ipa = (InteractivePointActive)ip; ipa.Tooltip = String.Format("K:{0}; IV:{1:#0.00}%\r\n{2} {3} @ {4}", sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx, DefaultOptQty); } }
protected static void FillNodeInfo(InteractivePointActive ip, double f, double dT, IOptionStrikePair sInfo, StrikeType optionType, OptionPxMode optPxMode, double optSigma, bool returnPct, bool isVisiblePoints) { if (optionType == StrikeType.Any) { throw new ArgumentException("Option type 'Any' is not supported.", "optionType"); } bool isCall = (optionType == StrikeType.Call); double optPx = FinMath.GetOptionPrice(f, sInfo.Strike, dT, optSigma, 0, isCall); SmileNodeInfo nodeInfo = new SmileNodeInfo(); nodeInfo.F = f; nodeInfo.dT = dT; nodeInfo.Sigma = returnPct ? optSigma * Constants.PctMult : optSigma; nodeInfo.OptPx = optPx; nodeInfo.Strike = sInfo.Strike; nodeInfo.Security = (optionType == StrikeType.Put) ? sInfo.Put.Security : sInfo.Call.Security; nodeInfo.PxMode = optPxMode; nodeInfo.OptionType = optionType; nodeInfo.Pair = sInfo; //nodeInfo.ScriptTime = optTime; nodeInfo.CalendarTime = DateTime.Now; nodeInfo.Symbol = nodeInfo.Security.Symbol; nodeInfo.Expired = nodeInfo.Security.SecurityDescription.Expired; ip.Tag = nodeInfo; ip.Color = AlphaColors.Yellow; ip.IsActive = isVisiblePoints; ip.Geometry = Geometries.Ellipse; ip.DragableMode = DragableMode.None; //ip.Value = new System.Windows.Point(sInfo.Strike, nodeInfo.Sigma); ip.Tooltip = String.Format("F:{0}; K:{1}; IV:{2:#0.00}%\r\n{3} {4} @ {5}", f, sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx, DefaultOptQty); }
private void InteractiveSplineOnQuoteIvEvent(object sender, InteractiveActionEventArgs eventArgs) { OptionPxMode pxMode = (m_qty > 0) ? OptionPxMode.Ask : OptionPxMode.Bid; PositionsManager posMan = PositionsManager.GetManager(m_context); if (posMan.BlockTrading) { //string msg = String.Format("[{0}] Trading is blocked. Please, change 'Block Trading' parameter.", m_optionPxMode); string msg = RM.GetStringFormat("OptHandlerMsg.PositionsManager.TradingBlocked", pxMode); m_context.Log(msg, MessageType.Info, true); return; } InteractivePointActive tmp = eventArgs.Point; if ((tmp == null) || (tmp.IsActive == null) || (!tmp.IsActive.Value) || DoubleUtil.IsZero(m_qty)) { //string msg = String.Format("[{0}] Unable to get direction of the order. Qty:{1}", pxMode, m_qty); string msg = RM.GetStringFormat("OptHandlerMsg.PositionsManager.UndefinedOrderDirection", pxMode, m_qty); m_context.Log(msg, MessageType.Error, true); return; } SmileNodeInfo nodeInfo = tmp.Tag as SmileNodeInfo; if (nodeInfo == null) { //string msg = String.Format("[{0}] There is no nodeInfo. Quote type: {1}; Strike: {2}", pxMode); string msg = RM.GetStringFormat(CultureInfo.InvariantCulture, "OptHandlerMsg.ThereIsNoNodeInfo", m_context.Runtime.TradeName, pxMode, eventArgs.Point.ValueX); m_context.Log(msg, MessageType.Error, true); return; } { string msg = String.Format(CultureInfo.InvariantCulture, "[{0}.ClickEvent] Strike: {1}", GetType().Name, tmp.ValueX); m_context.Log(msg, MessageType.Info, false); } nodeInfo.OptPx = m_shiftIv; nodeInfo.ShiftOptPx = m_shiftPriceStep; nodeInfo.ClickTime = DateTime.Now; nodeInfo.PxMode = pxMode; // [2015-10-02] Подписка на данный инструмент, чтобы он появился в коллекции Context.Runtime.Securities var candids = (from s in Context.Runtime.Securities where s.SecurityDescription.Name.Equals(nodeInfo.Symbol, StringComparison.InvariantCultureIgnoreCase) select s).ToList(); candids = (from s in candids where s.SecurityDescription.DSName.Equals(nodeInfo.DSName, StringComparison.InvariantCultureIgnoreCase) select s).ToList(); ISecurity testSec = (from s in candids let secDesc = s.SecurityDescription where secDesc.FullName.Equals(nodeInfo.FullName, StringComparison.InvariantCultureIgnoreCase) select s).SingleOrDefault(); if ((testSec == null) && (nodeInfo.Security != null)) { ISecurity sec = nodeInfo.Security; int bc = sec.Bars.Count; string msg = String.Format("[{0}] There is security DsName: {1}; Symbol: {2}; Security: {3} with {4} bars available.", pxMode, nodeInfo.DSName, nodeInfo.Symbol, nodeInfo.FullName, bc); Context.Log(msg, MessageType.Info, false); // Пересчитываю целочисленный параметр Qty в фактические лоты конкретного инструмента double actQty = Math.Abs(m_qty * sec.LotTick); // Модуль, потому что тут направление передается через PxMode nodeInfo.Qty = actQty; } else if ((nodeInfo.Pair != null) && (nodeInfo.Pair.Put != null)) { // Аварийная ветка // Пересчитываю целочисленный параметр Qty в фактические лоты конкретного инструмента double actQty = Math.Abs(m_qty * nodeInfo.Pair.Put.LotTick); // Модуль, потому что тут направление передается через PxMode nodeInfo.Qty = actQty; } else { // Аварийная ветка // Не могу пересчитать целочисленный параметр Qty в фактические лоты конкретного инструмента! //double actQty = Math.Abs(m_qty * nodeInfo.Pair.Put.LotTick); nodeInfo.Qty = Math.Abs(m_qty); // Модуль, потому что тут направление передается через PxMode string msg = String.Format(CultureInfo.InvariantCulture, "[{0}.ClickEvent] LotTick will be set to 1.", GetType().Name); m_context.Log(msg, MessageType.Warning, false); } // Не страшно, если сюда пойдет null - posMan потом сам найдет нужный опцион nodeInfo.Security = testSec; // Передаю событие в PositionsManager //posMan.InteractiveSplineOnClickEvent(m_context, sender, eventArgs); posMan.InteractiveSplineOnQuoteIvEvent(m_context, sender, eventArgs); }
/// <summary> /// Вычисление цены опциона различными способами. Есть возможность сразу сделать сдвиг цены (предусмотрены проверки). /// </summary> /// <param name="externalContext">Контекст блока для логгирования проблемы</param> /// <param name="f">Цена БА (нажна как верхняя оценка цены колла</param> /// <param name="sec">Инструмент</param> /// <param name="mode">алгоритм расчета (покупка, продажа, середина спреда)</param> /// <param name="shiftAsk">сдвиг асков</param> /// <param name="shiftBid">сдвиг бидов</param> /// <param name="qty">количество лотов в заявке</param> /// <param name="optTime">время получения этих котировок из рыночного провайдера</param> /// <returns>цена опциона (в случае проблем возвращает NaN)</returns> public static double GetOptPrice(IContext externalContext, double f, IOptionStrike sec, OptionPxMode mode, double shiftAsk, double shiftBid, out double qty, out DateTime optTime) { qty = Double.NaN; optTime = new DateTime(); double optPx = Double.NaN; // PROD-5952 - Не надо дергать стакан без нужды //sec.UpdateQueueData(); if (mode == OptionPxMode.Ask) { if (/* sec.FinInfo.AskSize.HasValue && */ sec.FinInfo.Ask.HasValue) { optPx = sec.FinInfo.Ask.Value; optTime = sec.FinInfo.LastUpdate; qty = 0; if (sec.FinInfo.AskSize.HasValue) { qty = sec.FinInfo.AskSize.Value; } else { // PROD-5952 - Не надо дергать стакан без нужды //// Аски отсортированы по возрастанию //var queue = sec.GetSellQueue(externalContext.BarsCount - 1); //if ((queue != null) && (queue.Count > 0)) //{ // IQueueData ask = queue[0]; // queue.First(); // qty = ask.Quantity; //} } } else { // PROD-5952 - Не надо дергать стакан без нужды #region Нет данных в FinInfo // // Аски отсортированы по возрастанию // var queue = sec.GetSellQueue(externalContext.BarsCount - 1); // if ((queue != null) && (queue.Count > 0)) // { // IQueueData ask = queue[0]; // queue.First(); //#if DEBUG // if (!s_conflictDate.ContainsKey(sec.Security.SecurityDescription.FullName)) // { // bool check = (ask.Security.FullName == sec.Security.SecurityDescription.FullName); // if (!check) // s_conflictDate[sec.Security.SecurityDescription.FullName] = ask.LastUpdate; // Debug.Assert(check, // String.Format("Expected security: {0}; actual security: {1}", // sec.Security.SecurityDescription.FullName, ask.Security.FullName)); // } //#endif // optPx = ask.Price; // qty = ask.Quantity; // optTime = ask.LastUpdate; // //string msg = // // String.Format( // // "[DEBUG:{0}] I was forced to use 'sec.GetSellQueue'. sec.Bars.Count:{1}; ask.LastUpdate:{2}; sec:{3}", // // typeof(IvSmile).Name, sec.Bars.Count, // // ask.LastUpdate.ToString(DateTimeFormatWithMs, CultureInfo.InvariantCulture), // // sec); // //externalContext.Log(msg, MessageType.Warning, true); // } #endregion Нет данных в FinInfo } if (Double.IsNaN(optPx) || (optPx <= Double.Epsilon)) { optPx = 2 * f; // Это одна из верхних оценок цены опциона. } else { optPx += shiftAsk; } } else if (mode == OptionPxMode.Bid) { if (/* sec.FinInfo.BidSize.HasValue && */ sec.FinInfo.Bid.HasValue) { optPx = sec.FinInfo.Bid.Value; optTime = sec.FinInfo.LastUpdate; qty = 0; if (sec.FinInfo.BidSize.HasValue) { qty = sec.FinInfo.BidSize.Value; } else { // PROD-5952 - Не надо дергать стакан без нужды //// Биды отсортированы ПО УБЫВАНИЮ!!! //var queue = sec.GetBuyQueue(externalContext.BarsCount - 1); //if ((queue != null) && (queue.Count > 0)) //{ // IQueueData bid = queue[0]; // queue.First(); // qty = bid.Quantity; //} } } else { // PROD-5952 - Не надо дергать стакан без нужды #region Нет данных в FinInfo // // Биды отсортированы ПО УБЫВАНИЮ!!! // var queue = sec.GetBuyQueue(externalContext.BarsCount - 1); // if ((queue != null) && (queue.Count > 0)) // { // IQueueData bid = queue[0]; // queue.First(); //#if DEBUG // if (!s_conflictDate.ContainsKey(sec.Security.SecurityDescription.FullName)) // { // bool check = (bid.Security.FullName == sec.Security.SecurityDescription.FullName); // if (!check) // s_conflictDate[sec.Security.SecurityDescription.FullName] = bid.LastUpdate; // Debug.Assert(check, // String.Format("Expected security: {0}; actual security: {1}", // sec.Security.SecurityDescription.FullName, bid.Security.FullName)); // } //#endif // optPx = bid.Price; // qty = bid.Quantity; // optPx -= shiftBid; // optPx = Math.Max(optPx, 0); // optTime = bid.LastUpdate; // //string msg = // // String.Format( // // "[DEBUG:{0}] I was forced to use 'sec.GetSellQueue'. sec.Bars.Count:{1}; bid.LastUpdate:{2}; sec:{3}", // // typeof(IvSmile).Name, sec.Bars.Count, // // bid.LastUpdate.ToString(DateTimeFormatWithMs, CultureInfo.InvariantCulture), // // sec); // //externalContext.Log(msg, MessageType.Warning, true); // } #endregion Нет данных в FinInfo } } else if (mode == OptionPxMode.Mid) { if (/* sec.FinInfo.BidSize.HasValue && */ sec.FinInfo.Bid.HasValue && /* sec.FinInfo.AskSize.HasValue && */ sec.FinInfo.Ask.HasValue) { double askPx = sec.FinInfo.Ask.Value; //double askQty = sec.FinInfo.AskSize.Value; if (Double.IsNaN(askPx) || (askPx <= Double.Epsilon)) { askPx = 2.0 * f; // Это одна из верхних оценок цены опциона. } else { askPx += shiftAsk; } double bidPx = sec.FinInfo.Bid.Value; //double bidQty = sec.FinInfo.BidSize.Value; bidPx -= shiftBid; bidPx = Math.Max(bidPx, 0); optPx = (askPx + bidPx) / 2.0; //qty = Math.Min(askQty, bidQty); double askQty = 0, bidQty = 0; #region AskQty if (sec.FinInfo.AskSize.HasValue) { askQty = sec.FinInfo.AskSize.Value; } else { // PROD-5952 - Не надо дергать стакан без нужды //// Аски отсортированы по возрастанию //var queue = sec.GetSellQueue(externalContext.BarsCount - 1); //if ((queue != null) && (queue.Count > 0)) //{ // IQueueData ask = queue[0]; // queue.First(); // askQty = ask.Quantity; //} } #endregion AskQty #region BidQty if (sec.FinInfo.BidSize.HasValue) { bidQty = sec.FinInfo.BidSize.Value; } else { // PROD-5952 - Не надо дергать стакан без нужды //// Биды отсортированы ПО УБЫВАНИЮ!!! //var queue = sec.GetBuyQueue(externalContext.BarsCount - 1); //if ((queue != null) && (queue.Count > 0)) //{ // IQueueData bid = queue[0]; // queue.First(); // bidQty = bid.Quantity; //} } #endregion BidQty qty = Math.Min(askQty, bidQty); optTime = sec.FinInfo.LastUpdate; } else { // PROD-5952 - Не надо дергать стакан без нужды #region Нет данных в FinInfo // var askQueue = sec.GetSellQueue(externalContext.BarsCount - 1); // var bidQueue = sec.GetBuyQueue(externalContext.BarsCount - 1); // if ((askQueue != null) && (askQueue.Count > 0) && // (bidQueue != null) && (bidQueue.Count > 0)) // { // // Аски отсортированы по возрастанию // IQueueData ask = askQueue[0]; // askQueue.First(); //#if DEBUG // if (!s_conflictDate.ContainsKey(sec.Security.SecurityDescription.FullName)) // { // bool check = (ask.Security.FullName == sec.Security.SecurityDescription.FullName); // if (!check) // s_conflictDate[sec.Security.SecurityDescription.FullName] = ask.LastUpdate; // Debug.Assert(check, // String.Format("Expected security: {0}; actual security: {1}", // sec.Security.SecurityDescription.FullName, ask.Security.FullName)); // } //#endif // double askPx = ask.Price; // double askQty = ask.Quantity; // if (Double.IsNaN(askPx) || (askPx <= Double.Epsilon)) // askPx = 2.0 * f; // Это одна из верхних оценок цены опциона. // else // askPx += shiftAsk; // // Биды отсортированы ПО УБЫВАНИЮ!!! // IQueueData bid = bidQueue[0]; // bidQueue.First(); //#if DEBUG // if (!s_conflictDate.ContainsKey(sec.Security.SecurityDescription.FullName)) // { // bool check = (bid.Security.FullName == sec.Security.SecurityDescription.FullName); // if (!check) // s_conflictDate[sec.Security.SecurityDescription.FullName] = bid.LastUpdate; // Debug.Assert(check, // String.Format("Expected security: {0}; actual security: {1}", // sec.Security.SecurityDescription.FullName, bid.Security.FullName)); // } //#endif // double bidPx = bid.Price; // double bidQty = bid.Quantity; // bidPx -= shiftBid; // bidPx = Math.Max(bidPx, 0); // optPx = (askPx + bidPx) / 2.0; // qty = Math.Min(askQty, bidQty); // optTime = (bid.LastUpdate < ask.LastUpdate) ? ask.LastUpdate : bid.LastUpdate; // } #endregion Нет данных в FinInfo } } else { throw new NotImplementedException("OptPxMode:" + mode); } return(optPx); }
internal static void FillNodeInfo(InteractivePointActive ip, double f, double dT, IOptionStrikePair sInfo, StrikeType optionType, OptionPxMode optPxMode, double optPx, double optQty, double optSigma, DateTime optTime, bool returnPct, double riskfreeRatePct) { if (optionType == StrikeType.Any) { throw new ArgumentException("Option type 'Any' is not supported.", "optionType"); } // ReSharper disable once UseObjectOrCollectionInitializer SmileNodeInfo nodeInfo = new SmileNodeInfo(); nodeInfo.F = f; nodeInfo.dT = dT; nodeInfo.RiskFreeRate = riskfreeRatePct; nodeInfo.Sigma = returnPct ? optSigma * Constants.PctMult : optSigma; nodeInfo.OptPx = optPx; nodeInfo.Strike = sInfo.Strike; // Сюда мы приходим когда хотим торговать, поэтому обращение к Security уместно nodeInfo.Security = (optionType == StrikeType.Put) ? sInfo.Put.Security : sInfo.Call.Security; nodeInfo.PxMode = optPxMode; nodeInfo.OptionType = optionType; nodeInfo.Pair = sInfo; nodeInfo.ScriptTime = optTime; nodeInfo.CalendarTime = DateTime.Now; nodeInfo.Symbol = nodeInfo.Security.Symbol; nodeInfo.DSName = nodeInfo.Security.SecurityDescription.DSName; nodeInfo.Expired = nodeInfo.Security.SecurityDescription.Expired; nodeInfo.FullName = nodeInfo.Security.SecurityDescription.FullName; ip.Tag = nodeInfo; ip.DragableMode = DragableMode.None; ip.Value = new Point(sInfo.Strike, nodeInfo.Sigma); // [2015-08-26] Алексей дал инструкцию убрать дату из тултипа. bool tooltipWithTime = false; #if DEBUG tooltipWithTime = true; #endif // [2015-12-07] В режиме отладки возвращаю. // Потому что иначе вообще непонятно что происходит и с какими данными скрипт работает. if (optQty > 0) { if (tooltipWithTime) { ip.Tooltip = String.Format(CultureInfo.InvariantCulture, "K:{0}; IV:{1:#0.00}%\r\n{2} px {3} @ {4}\r\nDate: {5}", sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx, optQty, optTime.ToString(DateTimeFormatWithMs, CultureInfo.InvariantCulture)); } else { ip.Tooltip = String.Format(CultureInfo.InvariantCulture, "K:{0}; IV:{1:#0.00}%\r\n{2} px {3} @ {4}", sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx, optQty); } } else { if (tooltipWithTime) { ip.Tooltip = String.Format(CultureInfo.InvariantCulture, "K:{0}; IV:{1:#0.00}%\r\n{2} px {3}\r\nDate: {4}", sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx, optTime.ToString(DateTimeFormatWithMs, CultureInfo.InvariantCulture)); } else { ip.Tooltip = String.Format(CultureInfo.InvariantCulture, "K:{0}; IV:{1:#0.00}%\r\n{2} px {3}", sInfo.Strike, optSigma * Constants.PctMult, optionType, optPx); } } }