protected override bool TryCalculate(Dictionary <DateTime, double> history, DateTime now, int barNum, object[] args, out double val) { IOption opt = (IOption)args[0]; double risk = 0; DateTime today = now.Date; PositionsManager posMan = PositionsManager.GetManager(m_context); foreach (IOptionSeries optSer in opt.GetSeries()) { if (optSer.ExpirationDate.Date < today) { continue; } IOptionStrikePair[] pairs = optSer.GetStrikePairs().ToArray(); for (int j = 0; j < pairs.Length; j++) { IOptionStrikePair pair = pairs[j]; double putQty, callQty; SingleSeriesPositionGrid.GetPairQty(posMan, pair, out putQty, out callQty); risk += Math.Abs(putQty + callQty); } } val = risk; return(true); }
/// <summary> /// Обработчик под тип входных данных OPTION /// </summary> public void Execute(IOption opt) { if (opt == null) { return; } DateTime now = opt.UnderlyingAsset.FinInfo.LastUpdate; DateTime today = now.Date; IOptionSeries[] series = opt.GetSeries().ToArray(); for (int j = 0; j < series.Length; j++) { IOptionSeries optSer = series[j]; if (optSer.ExpirationDate.Date < today) { continue; } try { double ivAtm; TryProcessSeries(optSer, now, out ivAtm); } catch (Exception ex) { string msg = String.Format("[{0}] {1} when processing option series: {2}", GetType().Name, ex.GetType().FullName, ex); m_context.Log(msg, MessageType.Warning, true); } } }
public double Execute(ISecurity source, IOption option, ISecurity zeroPricesSec, int barNum) { if (barNum < 1) { return(0); } var strikeStep = option.GetSeries().First().GetStrikes().First().LotTick; var sigma = GetVolatility(source)[barNum]; var isLast = barNum == source.Bars.Count - 1; var ct = source.Bars[barNum].Date; var price = zeroPricesSec.Bars[barNum].Close; var hasExpirations = false; foreach (var pos in source.Positions.GetActiveForBar(barNum).ToArray()) { var name = pos.EntrySignalName; if (name.Length < 4) { continue; } var isCall = name.StartsWith("C"); var expiration = ExpirationUtil.FromChar(name[1]); var expDate = pos.EntryBar.Date.GetExpirationDate(expiration); var isExp = ct >= expDate; hasExpirations |= isExp; var strikePrice = double.Parse(name.Substring(2)); if (isExp || isLast) { var closePrice = 0.0; if (!isCall && price < strikePrice) { closePrice = (strikePrice - price) / price; } else if (isCall && price > strikePrice) { closePrice = (price - strikePrice) / price; } pos.VirtualChange(barNum + 1, closePrice, 0, $"Exp-{name}"); } else { var dT = ct.GetDt(expiration); // it makes sell more low var optPx = strikePrice.GetOptPx(strikeStep, isCall, price, dT, sigma * 0.9); if (optPx >= pos.EntryPrice + MinProfit) { pos.VirtualChange(barNum + 1, optPx, 0, $"X-{name}"); } } } return(hasExpirations ? 1 : 0); }
public double Execute(ISecurity source, IOption option, ISecurity priceSec, double strikePrice, bool signal, int barNum) { var expDate = source.Bars.Last().Date.GetExpirationDate(Expiration); var series = option.GetSeries().First(s => s.ExpirationDate == expDate); series.TryGetStrikePair(strikePrice, out var strikePair); var strike = strikePair.Call; return(MakeDeal(source, strike, priceSec, strikePrice, signal, barNum, true)); }
public double Execute(IOption opt, int barNumber) { double res = Execute(opt.UnderlyingAsset, barNumber); foreach (var ser in opt.GetSeries()) { double comm = Execute(ser, barNumber); res += comm; } return(res); }
/// <summary> /// Метод под флаг TemplateTypes.OPTION, чтобы подключаться к источнику-опциону /// </summary> public double Execute(IOption opt, int barNum) { double failRes = Constants.NaN; if (m_repeatLastPx) { failRes = Double.IsNaN(m_prevPx) ? Constants.NaN : m_prevPx; } if (opt == null) { return(failRes); } ISecurity sec = opt.UnderlyingAsset; int len = sec.Bars.Count; if (len <= 0) { return(failRes); } DateTime lastBarDate = sec.Bars[barNum].Date; DateTime today = lastBarDate.Date; IOptionSeries optSer = (from ser in opt.GetSeries() where (today <= ser.ExpirationDate.Date) orderby ser.ExpirationDate descending select ser).FirstOrDefault(); // В данном случае падать необязательно if (optSer == null) { return(failRes); } double res = Execute(optSer, barNum); return(res); }
private double EstimateTimeForGivenBar(IOption opt, ISecurity sec, DateTime now, DateTime prevBarDate, DateTime prevExpDate, out double timeAsDays, out double timeAsYears, out DateTime barDate, out DateTime expDate) { DateTime curDate; #region Get current date switch (m_dateMode) { case CurrentDateMode.FixedDate: curDate = m_fixedDate; break; case CurrentDateMode.CurrentDate: curDate = now.Date; break; case CurrentDateMode.Tomorrow: curDate = now.AddDays(1); break; case CurrentDateMode.NextWorkingDay: curDate = now.AddDays(1); while (!CalendarWithoutHolidays.Russia.IsWorkingDay(curDate)) { curDate = curDate.AddDays(1); } break; case CurrentDateMode.NextWeek: curDate = now.AddDays(7); break; default: throw new NotImplementedException("CurDateMode:" + m_dateMode); } #endregion Get current date //DateTime today = sec.Bars[j].Date; DateTime today = now.Date; // Если дата прежняя, то и дата экспирации ещё не должна измениться if (today == prevBarDate) { barDate = today; expDate = prevExpDate; } //else if ((prevExpDate - prevBarDate).TotalDays > 1) // А если бары недельные??? или месячные??? else { barDate = today; #region Get expiration date switch (m_expiryMode) { case ExpiryMode.FixedExpiry: expDate = m_expirationDate; break; case ExpiryMode.FirstExpiry: { if (opt == null) { expDate = sec.SecurityDescription.ExpirationDate; } else { IOptionSeries optSer = (from ser in opt.GetSeries() where (today <= ser.ExpirationDate.Date) orderby ser.ExpirationDate ascending select ser).FirstOrDefault(); // Если все серии уже умерли, вернуть последнюю, чтобы гарантировать возврат даты if (optSer == null) { optSer = (from ser in opt.GetSeries() orderby ser.ExpirationDate descending select ser).First(); } expDate = optSer.ExpirationDate; } } break; case ExpiryMode.LastExpiry: { if (opt == null) { expDate = sec.SecurityDescription.ExpirationDate; } else { IOptionSeries optSer = (from ser in opt.GetSeries() where (today <= ser.ExpirationDate.Date) orderby ser.ExpirationDate descending select ser).FirstOrDefault(); // Если все серии уже умерли, вернуть последнюю, чтобы гарантировать возврат даты if (optSer == null) { optSer = (from ser in opt.GetSeries() orderby ser.ExpirationDate descending select ser).First(); } expDate = optSer.ExpirationDate; } } break; case ExpiryMode.ExpiryByNumber: { if (opt == null) { expDate = sec.SecurityDescription.ExpirationDate; } else { IOptionSeries[] optSers = (from ser in opt.GetSeries() where (today <= ser.ExpirationDate.Date) orderby ser.ExpirationDate ascending select ser).ToArray(); int ind = Math.Min(m_seriesIndex - 1, optSers.Length - 1); ind = Math.Max(ind, 0); IOptionSeries optSer; // Если все серии уже умерли, вернуть последнюю, чтобы гарантировать возврат даты if (optSers.Length == 0) { optSer = (from ser in opt.GetSeries() orderby ser.ExpirationDate descending select ser).First(); } else { optSer = optSers[ind]; } expDate = optSer.ExpirationDate; } } break; default: throw new NotImplementedException("ExpirationMode:" + m_expiryMode); } #endregion Get expiration date } // Грубое решение для определения точного времени экспирации if (m_expiryMode != ExpiryMode.FixedExpiry) { expDate = expDate.Date + m_expirationTime; } double time = TimeToExpiry.GetDt(expDate, curDate, m_tRemainMode, m_useDays, out timeAsDays, out timeAsYears); return(time); }
/// <summary> /// Метод под флаг TemplateTypes.OPTION, чтобы подключаться к источнику-опциону /// </summary> public IOptionSeries Execute(IOption opt, int barNum) { ISecurity sec = opt.UnderlyingAsset; IDataBar bar = sec.Bars[barNum]; DateTime now = bar.Date; IOptionSeries optSer = null; switch (m_expiryMode) { case ExpiryMode.FixedExpiry: { optSer = (from ser in opt.GetSeries() let serExpDate = ser.ExpirationDate.Date where (now.Date <= serExpDate) && (m_expirationDate.Date == serExpDate) select ser).FirstOrDefault(); break; } case ExpiryMode.FirstExpiry: { optSer = (from ser in opt.GetSeries() where (now.Date <= ser.ExpirationDate.Date) orderby ser.ExpirationDate ascending select ser).FirstOrDefault(); break; } case ExpiryMode.LastExpiry: { optSer = (from ser in opt.GetSeries() where (now.Date <= ser.ExpirationDate.Date) orderby ser.ExpirationDate descending select ser).FirstOrDefault(); break; } case ExpiryMode.ExpiryByNumber: { IOptionSeries[] optSers = (from ser in opt.GetSeries() where (now.Date <= ser.ExpirationDate.Date) orderby ser.ExpirationDate ascending select ser).ToArray(); int ind = Math.Min(Number - 1, optSers.Length - 1); ind = Math.Max(ind, 0); // Если все серии уже умерли, вернуть null, чтобы потом не было непоняток // и чтобы поведение было согласовано с другими ветками if (optSers.Length == 0) { optSer = null; } else { optSer = optSers[ind]; } break; } default: throw new NotImplementedException("ExpirationMode:" + m_expiryMode); } // End of switch(m_expiryMode) // На последней свече логгирую if (barNum >= sec.Bars.Count - 1) { if (optSer == null) { string msg = String.Format("Unable to get option series from source '{0}'. ExpirationMode:{1}; Number:{2}; Expiry:{3}", sec.Symbol, ExpirationMode, Number, Expiry); // Пишу только в лог агента. Ситуация достаточно стандартная. // Например, когда фьючерс уже умер. m_context.Log(msg, MessageType.Warning, false); } //else //{ // string msg = String.Format("Option series '{0}' from source '{1}'. ExpirationMode:{2}; Number:{3}; Expiry:{4}", // optSer.ExpirationDate.ToString(IvOnF.DateFormat, CultureInfo.InvariantCulture), // sec.Symbol, ExpirationMode, Number, Expiry); // // Пишу только в лог агента. Ситуация стандартная. // m_context.Log(msg, MessageType.Info, false); //} } return(optSer); }
/// <summary> /// Метод под флаг TemplateTypes.OPTION, чтобы подключаться к источнику-опциону /// </summary> public IOptionSeries Execute(IOption opt) { ISecurity sec = opt.UnderlyingAsset; if (sec.Bars.Count <= 0) { return(null); } int len = sec.Bars.Count; switch (m_expiryMode) { case ExpiryMode.FixedExpiry: { IDataBar bar = sec.Bars[len - 1]; DateTime now = bar.Date; IOptionSeries optSer = (from ser in opt.GetSeries() let serExpDate = ser.ExpirationDate.Date where (now.Date <= serExpDate) && (m_expirationDate.Date == serExpDate) select ser).FirstOrDefault(); return(optSer); } case ExpiryMode.FirstExpiry: { IDataBar bar = sec.Bars[len - 1]; DateTime now = bar.Date; IOptionSeries optSer = (from ser in opt.GetSeries() where (now.Date <= ser.ExpirationDate.Date) orderby ser.ExpirationDate ascending select ser).FirstOrDefault(); //// Если все серии уже умерли, вернуть последнюю, чтобы гарантировать возврат даты //if (optSer == null) //{ // optSer = (from ser in opt.GetSeries() // orderby ser.ExpirationDate descending // select ser).First(); //} ////expDate = optSer.ExpirationDate; return(optSer); } case ExpiryMode.LastExpiry: { IDataBar bar = sec.Bars[len - 1]; DateTime now = bar.Date; IOptionSeries optSer = (from ser in opt.GetSeries() where (now.Date <= ser.ExpirationDate.Date) orderby ser.ExpirationDate descending select ser).FirstOrDefault(); //expDate = optSer.ExpirationDate; return(optSer); } case ExpiryMode.ExpiryByNumber: { IDataBar bar = sec.Bars[len - 1]; DateTime now = bar.Date; IOptionSeries[] optSers = (from ser in opt.GetSeries() where (now.Date <= ser.ExpirationDate.Date) orderby ser.ExpirationDate ascending select ser).ToArray(); int ind = Math.Min(Number - 1, optSers.Length - 1); ind = Math.Max(ind, 0); IOptionSeries optSer; // Если все серии уже умерли, вернуть null, чтобы потом не было непоняток // и чтобы поведение было согласовано с другими ветками if (optSers.Length == 0) { optSer = null; } else { optSer = optSers[ind]; } return(optSer); } default: throw new NotImplementedException("ExpirationMode:" + m_expiryMode); } }
/// <summary> /// Общий метод формирования списка префиксов /// </summary> private IOption Select(params IOption[] options) { if ((options == null) || (options.Length <= 0)) { string msg = String.Format("Empty argument '{0}' is not supported. I return NULL immediately.", "options"); return(null); } HashSet <string> prefList = PrefixList; prefList.Clear(); HashSet <string> serList = SeriesList; serList.Clear(); IOption res = null; //DateTime now = bar.Date; bool seriesFound = false; for (int j = 0; j < options.Length; j++) { IOption opt = options[j]; if (opt == null) { continue; } string prefix = opt.UnderlyingAsset.Symbol.Substring(0, 2); prefList.Add(prefix); // Заполняю ВСЕ серии // TODO: использовать только активные??? foreach (var ser in opt.GetSeries()) { char month = s_monthLetters[ser.ExpirationDate.Month - 1]; string serName = prefix + month + (ser.ExpirationDate.Year % 10); serList.Add(serName); // Здесь идея в том, что при работе на двух комбиках внешнее состояние дочернего бокса меняется правильно, // а внутреннее остаётся некорректным. Поэтому помимо точного совпадения серий надо перепроверять ещё и префикс. if ((serName.Equals(m_optionSeries, StringComparison.InvariantCultureIgnoreCase)) && (prefix.StartsWith(m_baseSecPrefix, StringComparison.InvariantCultureIgnoreCase))) { res = opt; // НАШЛИ ОПЦИОН! УРА! seriesFound = true; } } // Нашли БА? Отлично! Надо его запомнить на всякий случай. Но только первый раз. if (prefix.StartsWith(m_baseSecPrefix, StringComparison.InvariantCultureIgnoreCase)) { if ((res == null) && (!seriesFound)) { res = opt; } } } // Если серию найти не удалось, восстанавливаю значения переменных и возвращаю первый аргумент if ((res == null) && (options.Length > 0) && (options[0] != null)) { res = options[0]; string msg = String.Format(RM.GetString("OptHandlerMsg.OptionSelector.OptionSeriesNotFound"), m_baseSecPrefix, m_optionSeries, res.Symbol); m_context.Log(msg, MessageType.Error); } return(res); }
/// <summary> /// Обработчик под тип входных данных OPTION (1 аргумент) /// </summary> public IOptionSeries Execute(IOption opt) { IOptionSeries res = Select(opt.GetSeries().ToArray()); return(res); }