public CallState(long id, IContext context, IDataSourceSecurity dataSourceSecurity, bool onlyAtTradingSession) { Contract.Assert(context != null, "Почему вдруг (context==null) ??"); Contract.Assert(dataSourceSecurity != null, "Почему вдруг (dataSourceSecurity==null) ??"); CallId = id; CallContext = context; SecInfo = new PositionsManager.SecInfo(dataSourceSecurity); OnlyAtTradingSession = onlyAtTradingSession; DataSourceSecurity = dataSourceSecurity; }
public bool Equals(IDataSourceSecurity secDesc) { if (secDesc == null) { return(false); } // проверка специально разбита на 3 части, чтобы легче было дебажить bool res = FullName.Equals(secDesc.FullName, StringComparison.InvariantCultureIgnoreCase); res &= Name.Equals(secDesc.Name, StringComparison.InvariantCultureIgnoreCase); res &= DsName.Equals(secDesc.DSName, StringComparison.InvariantCultureIgnoreCase); return(res); }
public SecInfo(IDataSourceSecurity sec) { m_name = sec.Name; m_dsName = sec.DSName; m_fullName = sec.FullName; m_strike = sec.Strike; m_isOption = sec.IsOption; m_expiry = sec.ExpirationDate; if (m_isOption) { if (sec.ActiveType == ActiveType.OptionPut) { m_strikeType = Script.Options.StrikeType.Put; } else if (sec.ActiveType == ActiveType.OptionCall) { m_strikeType = Script.Options.StrikeType.Call; } } }
public IList <double> Execute(IGraphPane pane, ISecurity security) { if (pane == null) { throw new ArgumentNullException(nameof(pane)); } if (security == null) { throw new ArgumentNullException(nameof(security)); } m_dataSourceSecurity = security.SecurityDescription; var id = typeof(IInteractiveLineGen).Name + "." + VariableId; var container = (NotClearableContainer <InteractiveLineGen>)Context.LoadObject(id); container?.Content.Unsubscribe(); var result = GetLine(pane, m_bars = security.Bars); Subscribe(); Context.StoreObject(id, new NotClearableContainer <InteractiveLineGen>(this)); return(result); }
public DataSourceSecurity(IDataSourceSecurity source) { m_source = source ?? throw new ArgumentNullException(nameof(source)); }
/// <summary> /// Метод под флаг TemplateTypes.INTERACTIVESPLINE /// </summary> public InteractiveSeries Execute(InteractiveSeries smile, IOptionSeries optSer, InteractiveSeries quoteIv, double scaleMult, int barNum) { if ((smile == null) || (optSer == null)) { return(Constants.EmptySeries); } m_dataSourceSecurity = optSer.UnderlyingAsset.SecurityDescription; int barsCount = m_context.BarsCount; if (!m_context.IsLastBarUsed) { barsCount--; } if (barNum < barsCount - 1) { return(Constants.EmptySeries); } SmileInfo oldInfo = smile.GetTag <SmileInfo>(); if ((oldInfo == null) || (oldInfo.ContinuousFunction == null)) { return(Constants.EmptySeries); } double futPx = oldInfo.F; double dT = oldInfo.dT; // 1. Формируем маркеры заявок List <InteractiveObject> controlPoints = new List <InteractiveObject>(); PositionsManager posMan = PositionsManager.GetManager(m_context); IList <PositionsManager.IvTargetInfo> ivTargets = posMan.GetIvTargets(m_isLong, true); for (int j = 0; j < ivTargets.Count; j++) { var ivTarget = ivTargets[j]; // PROD-6102 - Требуется точное совпадение опционной серии if (optSer.ExpirationDate.Date != ivTarget.SecInfo.Expiry.Date) { // Вывести предупреждение??? continue; } IOptionStrikePair pair; double k = ivTarget.SecInfo.Strike; if (!optSer.TryGetStrikePair(k, out pair)) { // Вывести предупреждение??? continue; } double sigma; QuoteIvMode quoteMode = ivTarget.QuoteMode; if (quoteMode == QuoteIvMode.Absolute) { sigma = ivTarget.EntryIv; } else { sigma = oldInfo.ContinuousFunction.Value(k) + ivTarget.EntryIv; if (!DoubleUtil.IsPositive(sigma)) { //string msg = String.Format("[DEBUG:{0}] Invalid sigma:{1} for strike:{2}", GetType().Name, sigma, nodeInfo.Strike); //m_context.Log(msg, MessageType.Warning, true); continue; } } bool isCall = (futPx <= k); if ((ivTarget.SecInfo.StrikeType != null) && (ivTarget.SecInfo.StrikeType.Value != StrikeType.Any)) { isCall = (ivTarget.SecInfo.StrikeType.Value == StrikeType.Call); } StrikeType optionType = isCall ? StrikeType.Call : StrikeType.Put; Contract.Assert(pair.Tick < 1, $"На тестовом контуре Дерибит присылает неправильный шаг цены! Tick:{pair.Tick}; Decimals:{pair.Put.Security.Decimals}"); double theorOptPxDollars = FinMath.GetOptionPrice(futPx, pair.Strike, dT, sigma, oldInfo.RiskFreeRate, isCall); // Сразу(!!!) переводим котировку из баксов в битки double theorOptPxBitcoins = theorOptPxDollars / scaleMult; // Сдвигаем цену в долларах (с учетом ш.ц. в баксах) theorOptPxDollars += ivTarget.EntryShiftPrice * pair.Tick * scaleMult; theorOptPxDollars = Math.Round(theorOptPxDollars / (pair.Tick * scaleMult)) * (pair.Tick * scaleMult); // Сдвигаем цену в биткойнах (с учетом ш.ц. в битках) theorOptPxBitcoins += ivTarget.EntryShiftPrice * pair.Tick; theorOptPxBitcoins = Math.Round(theorOptPxBitcoins / pair.Tick) * pair.Tick; if ((!DoubleUtil.IsPositive(theorOptPxBitcoins)) || (!DoubleUtil.IsPositive(theorOptPxDollars))) { //string msg = String.Format("[DEBUG:{0}] Invalid theorOptPx:{1} for strike:{2}", GetType().Name, theorOptPx, nodeInfo.Strike); //m_context.Log(msg, MessageType.Warning, true); continue; } // Пересчитываем сигму обратно, ЕСЛИ мы применили сдвиг цены в абсолютном выражении if (ivTarget.EntryShiftPrice != 0) { sigma = FinMath.GetOptionSigma(futPx, pair.Strike, dT, theorOptPxDollars, oldInfo.RiskFreeRate, isCall); if (!DoubleUtil.IsPositive(sigma)) { //string msg = String.Format("[DEBUG:{0}] Invalid sigma:{1} for strike:{2}", GetType().Name, sigma, nodeInfo.Strike); //m_context.Log(msg, MessageType.Warning, true); continue; } } double totalQty; if (isCall) { totalQty = posMan.GetTotalQty(pair.Call.Security, m_context.BarsCount, TotalProfitAlgo.AllPositions, ivTarget.IsLong); } else { totalQty = posMan.GetTotalQty(pair.Put.Security, m_context.BarsCount, TotalProfitAlgo.AllPositions, ivTarget.IsLong); } double targetQty = Math.Abs(ivTarget.TargetShares) - totalQty; // ReSharper disable once UseObjectOrCollectionInitializer InteractivePointActive tmp = new InteractivePointActive(); // Попробуем по-простому? tmp.Tag = ivTarget; tmp.IsActive = true; tmp.ValueX = k; tmp.ValueY = sigma; tmp.DragableMode = DragableMode.None; if (ivTarget.EntryShiftPrice == 0) { tmp.Tooltip = String.Format(CultureInfo.InvariantCulture, " F: {0}\r\n K: {1}; IV: {2:P2}\r\n {3} px {4} rIV {5:P2} @ {6}", futPx, k, sigma, optionType, theorOptPxBitcoins, ivTarget.EntryIv, targetQty); } else { string shiftStr = (ivTarget.EntryShiftPrice > 0) ? "+" : "-"; shiftStr = shiftStr + Math.Abs(ivTarget.EntryShiftPrice) + "ps"; tmp.Tooltip = String.Format(CultureInfo.InvariantCulture, " F: {0}\r\n K: {1}; IV: {2:P2}\r\n {3} px {4} rIV {5:P2} {6} @ {7}", futPx, k, sigma, optionType, theorOptPxBitcoins, ivTarget.EntryIv, shiftStr, targetQty); } //tmp.Color = Colors.White; //if (m_qty > 0) // tmp.Geometry = Geometries.Triangle; //else if (m_qty < 0) // tmp.Geometry = Geometries.TriangleDown; //else // tmp.Geometry = Geometries.None; InteractiveObject obj = new InteractiveObject(); obj.Anchor = tmp; controlPoints.Add(obj); } // ReSharper disable once UseObjectOrCollectionInitializer InteractiveSeries res = new InteractiveSeries(); // Здесь так надо -- мы делаем новую улыбку res.ControlPoints = new ReadOnlyCollection <InteractiveObject>(controlPoints); if (controlPoints.Count > 0) { res.ClickEvent -= InteractiveSplineOnClickEvent; res.ClickEvent += InteractiveSplineOnClickEvent; m_clickableSeries = res; } return(res); }