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