/// <summary> /// Initializes a new instance of the <see cref="PriceableIceBrentFuture"/> class. /// </summary> /// <param name="baseDate">The base date.</param> /// <param name="nodeStruct">The nodeStruct.</param> /// <param name="rollCalendar">THe rollCalendar.</param> /// <param name="fixedRate"></param> public PriceableIceBrentFuture(DateTime baseDate, CommodityFutureNodeStruct nodeStruct, IBusinessCalendar rollCalendar, BasicQuotation fixedRate) : base(baseDate, nodeStruct.Future, nodeStruct.BusinessDayAdjustments, fixedRate, new Offset { dayType = DayTypeEnum.Business, dayTypeSpecified = true, period = PeriodEnum.D, periodMultiplier = "0", periodSpecified = true }) { Id = nodeStruct.Future.id; Future = nodeStruct.Future; PriceQuoteUnits = nodeStruct.PriceQuoteUnits; ModelIdentifier = "CommoditiesFuturesAsset"; SettlementBasis = "EFP Delivery with an option to cash settle."; ContractSeries = "Monthly"; var idParts = Id.Split('-'); //var exchangeCommodityName = idParts[2]; var immCode = idParts[3]; //Only the relative rolls. if (int.TryParse(immCode, out var intResult)) { var lastTradingDay = new FirstDayLessFifteen().GetNthLastTradingDay(baseDate, intResult); //Do the date adjustment logic. LastTradeDate = rollCalendar.Advance(lastTradingDay, RollOffset, BusinessDayConventionEnum.PRECEDING); RiskMaturityDate = LastTradeDate; TimeToExpiry = (decimal)DayCounter.YearFraction(BaseDate, RiskMaturityDate); } }
/// <summary> /// </summary> /// <param name="discountCurve"></param> /// <param name="tenor"></param> /// <param name="baseDate"></param> /// <param name="interpolatedCurve"></param> /// <param name="paymentCalendar"></param> /// <param name="dayCounter"></param> /// <returns></returns> /// <exception cref="System.Exception"></exception> public static TermCurve ToForwardCurve(TermCurve discountCurve, Period tenor, DateTime baseDate, InterpolatedCurve interpolatedCurve, IBusinessCalendar paymentCalendar, IDayCounter dayCounter) { TermCurve result = TermCurve.Create(new List <TermPoint>()); var length = discountCurve.point.Length; var offset = new Offset { dayType = DayTypeEnum.Calendar, dayTypeSpecified = true, period = tenor.period, periodMultiplier = tenor.periodMultiplier, periodSpecified = true }; if (paymentCalendar == null) { return(result); } for (int i = 0; i < length - 1; i++) //This will only go to the penultimate point. Extrapolation required for more. { var pointStart = discountCurve.point[i]; DateTime startDate = XsdClassesFieldResolver.TimeDimensionGetDate(pointStart.term); var endDate = paymentCalendar.Advance(startDate, offset, BusinessDayConventionEnum.FOLLOWING); var endPoint = new DateTimePoint1D(baseDate, endDate); var endDF = interpolatedCurve.Value(endPoint); double time = dayCounter.YearFraction(startDate, endDate); var forwardRateDouble = RateAnalytics.DiscountFactorsToForwardRate((double)pointStart.mid, endDF, time); TermPoint forwardPoint = TermPointFactory.Create(Convert.ToDecimal(forwardRateDouble), startDate); forwardPoint.id = tenor.id; result.Add(forwardPoint); } return(result); }
///// <summary> ///// Initializes a new instance of the <see cref="PriceableFxSpotRate"/> class. ///// </summary> ///// <param name="baseDate">The base date.</param> ///// <param name="spotDateOffset">The business day adjustments.</param> ///// <param name="fxRateAsset"></param> ///// <param name="fxForward">The forward points.</param> //public PriceableFxTNRate(DateTime baseDate, RelativeDateOffset spotDateOffset, FxRateAsset fxRateAsset, BasicQuotation fxForward) // : this(1.0m, baseDate, fxRateAsset, // spotDateOffset, fxForward) //{} /// <summary> /// Initializes a new instance of the <see cref="PriceableFxSpotRate"/> class. /// </summary> /// <param name="notionalAmount">The notional.</param> /// <param name="baseDate">The base date.</param> /// <param name="nodeStruct">The nodeStruct.</param> /// <param name="fxRateAsset">The asset itself</param> /// <param name="fixingCalendar">The fixing Calendar.</param> /// <param name="paymentCalendar">The payment Calendar.</param> /// <param name="fxForward">The forward points.</param> public PriceableFxTNRate(DateTime baseDate, decimal notionalAmount, FxSpotNodeStruct nodeStruct, FxRateAsset fxRateAsset, IBusinessCalendar fixingCalendar, IBusinessCalendar paymentCalendar, BasicQuotation fxForward) : base(baseDate, "1D", notionalAmount, nodeStruct, fxRateAsset, fixingCalendar, paymentCalendar, fxForward) { AdjustedStartDate = baseDate; //AdjustedEffectiveDate = fixingCalendar.Advance(AdjustedStartDate, OffsetHelper.FromInterval(Tenor, DayTypeEnum.Business), SpotDateOffset.businessDayConvention); RiskMaturityDate = fixingCalendar.Advance(AdjustedStartDate, OffsetHelper.FromInterval(Tenor, DayTypeEnum.Business), SpotDateOffset.businessDayConvention); }
/// <summary> /// Initializes a new instance of the <see cref="PriceableCash"/> class. /// </summary> /// <param name="baseDate"></param> /// <param name="cash">The deposit.</param> /// <param name="amount">The cah amount.</param> /// <param name="term">The term of the cash flow.</param> /// <param name="businessDayAdjustments">The business day adjustments.</param> /// <param name="fixedRate">The fixed rate.</param> /// <param name="paymentCalendar">The payment Calendar.</param> protected PriceableCash(DateTime baseDate, Asset cash, Decimal amount, Period term, IBusinessCalendar paymentCalendar, BusinessDayAdjustments businessDayAdjustments, BasicQuotation fixedRate) : base(cash.id, baseDate, amount, businessDayAdjustments, fixedRate) { Term = term; RiskMaturityDate = paymentCalendar.Advance(BaseDate, OffsetHelper.FromInterval(Term, DayTypeEnum.Calendar), BusinessDayAdjustments.businessDayConvention); YearFraction = (decimal)Actual365.Instance.YearFraction(BaseDate, RiskMaturityDate); }
///<summary> ///</summary> public DateTime GetSettlementDate(DateTime baseDate, IBusinessCalendar settlementCalendar, RelativeDateOffset settlementDateOffset) { try { return(settlementCalendar.Advance(baseDate, settlementDateOffset, settlementDateOffset.businessDayConvention)); } catch (System.Exception) { throw new System.Exception("No settlement calendar set."); } }
/// <summary> /// Advances the specified calendars. /// </summary> /// <param name="businessCalendar">The calendars.</param> /// <param name="date">The date.</param> /// <param name="dayTypeString">The day type string.</param> /// <param name="periodInterval">The period interval.</param> /// <param name="businessDayConvention">The business day convention.</param> /// <returns></returns> public static DateTime Advance(IBusinessCalendar businessCalendar, DateTime date, string dayTypeString, string periodInterval, string businessDayConvention) { //IBusinessCalendar calendar = GetCalendar(calendars, ruleFullFilePath); Period interval = PeriodHelper.Parse(periodInterval); var dayType = DayTypeEnum.Calendar; if (dayTypeString.Length > 0) { dayType = (DayTypeEnum)Enum.Parse(typeof(DayTypeEnum), dayTypeString, true); } Offset offset = OffsetHelper.FromInterval(interval, dayType); BusinessDayConventionEnum dayConvention = BusinessDayConventionHelper.Parse(businessDayConvention); return(businessCalendar.Advance(date, offset, dayConvention)); }
/// <summary> /// Converts to an adjusted date. /// </summary> /// <param name="referenceDate"></param> /// <param name="relativeDateOffset"></param> /// <param name="businessCalendar"></param> /// <returns></returns> public static DateTime ToAdjustedDate(IBusinessCalendar businessCalendar, DateTime referenceDate, RelativeDateOffset relativeDateOffset) { // handle BusinessDatConventionEnum is NONE as a special case, since there might be no business centers provided. if (BusinessDayConventionEnum.NONE == relativeDateOffset.businessDayConvention) { return(referenceDate); } //The default day type. if (relativeDateOffset.dayTypeSpecified == false || relativeDateOffset.businessCenters == null) { relativeDateOffset.dayType = DayTypeEnum.Calendar; } //IBusinessCalendar businessCalendar = relativeDateOffset.businessCenters == null ? new Hell() : BusinessCenterHelper.ToBusinessCalendar(cache, relativeDateOffset.businessCenters); var interval = PeriodHelper.Parse(relativeDateOffset.periodMultiplier + relativeDateOffset.period); var offset = OffsetHelper.FromInterval(interval, relativeDateOffset.dayType); DateTime result = businessCalendar.Advance(referenceDate, offset, relativeDateOffset.businessDayConvention); return(result); }
/// <summary> /// Initializes a new instance of the <see cref="PriceableCommodityFuturesAsset"/> class. /// </summary> /// <param name="baseDate">The base date.</param> /// <param name="nodeStruct">The nodeStruct.</param> /// <param name="rollCalendar">THe rollCalendar.</param> /// <param name="fixedRate"></param> public PriceableWheatFuture(DateTime baseDate, CommodityFutureNodeStruct nodeStruct, IBusinessCalendar rollCalendar, BasicQuotation fixedRate) : base(baseDate, nodeStruct.Future, nodeStruct.BusinessDayAdjustments, fixedRate, new Offset { dayType = DayTypeEnum.Business, dayTypeSpecified = true, period = PeriodEnum.D, periodMultiplier = "0", periodSpecified = true }) { Id = nodeStruct.Future.id; Future = nodeStruct.Future; PriceQuoteUnits = nodeStruct.PriceQuoteUnits; ModelIdentifier = "CommoditiesFuturesAsset"; SettlementBasis = "The business day prior to the 15th calendar day of the contract month"; ContractMonthPeriod = nodeStruct.ContractMonthPeriod; ContractSeries = "March (H), May (K), July (N), September (U) & December (Z)"; ExchangeIdentifier = nodeStruct.Future.exchangeId.Value; var idParts = Id.Split('-'); var exchangeCommodityNames = idParts[2].Split('.'); var commodityCode = exchangeCommodityNames[0]; if (exchangeCommodityNames.Length > 1) { commodityCode = exchangeCommodityNames[1]; } var immCode = idParts[3]; //Catch the relative rolls. if (int.TryParse(immCode, out int intResult)) { var tempTradingDate = LastTradingDayHelper.ParseCode(commodityCode); immCode = tempTradingDate.GetNthMainCycleCode(baseDate, intResult); } var lastTradingDay = LastTradingDayHelper.Parse(commodityCode, immCode); LastTradeDate = rollCalendar.Advance(lastTradingDay.GetLastTradingDay(baseDate), RollOffset, BusinessDayConventionEnum.PRECEDING); RiskMaturityDate = LastTradeDate; TimeToExpiry = (decimal)DayCounter.YearFraction(BaseDate, RiskMaturityDate); }
/// <summary> /// Gets the forward spot date. /// </summary> /// <returns></returns> protected DateTime GetForwardDate(DateTime spotDate, IBusinessCalendar paymentCalendar, Period tenor, BusinessDayConventionEnum businessDayConvention) { return(paymentCalendar.Advance(spotDate, OffsetHelper.FromInterval(tenor, DayTypeEnum.Calendar), businessDayConvention)); }
/// <summary> /// Initializes a new instance of the <see cref="PriceableLMEFuture"/> class. /// </summary> /// <param name="baseDate">The base date.</param> /// <param name="nodeStruct">The nodeStruct.</param> /// <param name="rollCalendar">THe rollCalendar.</param> /// <param name="fixedRate"></param> public PriceableLMEFuture(DateTime baseDate, CommodityFutureNodeStruct nodeStruct, IBusinessCalendar rollCalendar, BasicQuotation fixedRate) : base(baseDate, nodeStruct.Future, nodeStruct.BusinessDayAdjustments, fixedRate, new Offset { dayType = DayTypeEnum.Business, dayTypeSpecified = true, period = PeriodEnum.D, periodMultiplier = "0", periodSpecified = true }) { Id = nodeStruct.Future.id; CommodityType = Future.description; Future = nodeStruct.Future; PriceQuoteUnits = nodeStruct.PriceQuoteUnits; ModelIdentifier = "CommoditiesFuturesAsset"; SettlementBasis = "EFP Delivery with an option to cash settle."; ContractMonthPeriod = nodeStruct.ContractMonthPeriod; ContractSeries = "Daily:3M/Weekly:6M/Monthly:" + ContractMonthPeriod.ToString(); ExchangeIdentifier = nodeStruct.Future.exchangeId.Value; var idParts = Id.Split('-'); var immCode = idParts[3]; if (int.TryParse(immCode, out int intResult)) { //If the roll is less that 3M then daily roll. //Less the number of business days in the next 3 months i.e. approximately 60. //TODO This hsould be all moved to configuration! var dailyCutoverOffset = new Offset { dayType = DayTypeEnum.Calendar, dayTypeSpecified = true, period = PeriodEnum.M, periodMultiplier = "3", periodSpecified = true }; var dailyCutoverDate = rollCalendar.Advance(BaseDate, dailyCutoverOffset, BusinessDayConventionEnum.MODFOLLOWING); var businessDays = rollCalendar.BusinessDaysBetweenDates(BaseDate, dailyCutoverDate); if (intResult <= businessDays.Count) { LastTradeDate = businessDays[intResult]; } //TODO //If the roll is greater than 3M and less than 6M then weekly on a Wednesday. //Less the number of weeks in the following 3 months i.e. approximately 12 // else { //Remember thefirst expiry is after the 3 motn cutover! //TODO this should be the 6 ContractMonthPeriod. var rollDate = baseDate.AddMonths(intResult - businessDays.Count + 3); var lastTradingDay = new LastTradingDate().GetLastTradingDay(rollDate.Month, rollDate.Year); //Do the date adjustment logic. LastTradeDate = rollCalendar.Advance(lastTradingDay, RollOffset, BusinessDayConventionEnum.PRECEDING); } } //This means that the value should be a period. else { var term = PeriodHelper.Parse(immCode); LastTradeDate = GetEffectiveDate(BaseDate, rollCalendar, term, nodeStruct.BusinessDayAdjustments.businessDayConvention); } RiskMaturityDate = LastTradeDate; TimeToExpiry = (decimal)DayCounter.YearFraction(BaseDate, RiskMaturityDate); }
/// <summary> /// Calcs the date. /// </summary> /// <param name="xdt">The XDT.</param> /// <param name="nextCoupDate">The next coup date.</param> /// <param name="calendar">The calendar.</param> /// <returns></returns> public DateTime CalcDate(ExDividendEnum xdt, DateTime nextCoupDate, IBusinessCalendar calendar) { switch (xdt) { case ExDividendEnum.XD_7d: return(nextCoupDate.AddDays(-7)); case ExDividendEnum.XD_9d: return(nextCoupDate.AddDays(-9)); case ExDividendEnum.XD_14d: return(nextCoupDate.AddDays(-14)); case ExDividendEnum.XD_30d: return(nextCoupDate.AddDays(-30)); case ExDividendEnum.XD_1m: return(nextCoupDate.AddMonths(-1)); case ExDividendEnum.XD_4bd: { var minusFourDayInterval = new Offset { dayType = DayTypeEnum.Business, period = PeriodEnum.D, periodMultiplier = "-4" }; return(calendar.Advance(nextCoupDate, minusFourDayInterval, BusinessDayConventionEnum.PRECEDING)); } case ExDividendEnum.XD_6bd: { var minusSixDayInterval = new Offset { dayType = DayTypeEnum.Business, period = PeriodEnum.D, periodMultiplier = "-6" }; return(calendar.Advance(nextCoupDate, minusSixDayInterval, BusinessDayConventionEnum.PRECEDING)); } case ExDividendEnum.XD_10bd: { var minusTenDayInterval = new Offset { dayType = DayTypeEnum.Business, period = PeriodEnum.D, periodMultiplier = "-10" }; return(calendar.Advance(nextCoupDate, minusTenDayInterval, BusinessDayConventionEnum.PRECEDING)); } case ExDividendEnum.XD_Austria: throw new NotImplementedException("ExDividendEnum.XD_Austria"); //if (nextCoupDate.Day >= 10 && nextCoupDate.Day <= 24) return nextCoupDate.AddDays(Convert.ToDouble(9 - new DateTime(nextCoupDate.Year, nextCoupDate.Month, 1).DayOfWeek)); //return new DateTime(nextCoupDate.Year, nextCoupDate.Month, 22 - Convert.ToInt32(new DateTime(nextCoupDate.Year, nextCoupDate.Month - ((nextCoupDate.Day < 10)?0:1), 14).DayOfWeek)); case ExDividendEnum.XD_eurobond: int y = nextCoupDate.Year, m = nextCoupDate.Day, d = nextCoupDate.Day; if (d < 3) { d = 16; m--; } else if (d < 17) { d = 1; } else { d = 16; } return(new DateTime(y, m, d)); case ExDividendEnum.XD_Ireland: throw new NotImplementedException("ExDividendEnum.XD_Ireland"); //return nextCoupDate.AddDays(Convert.ToDouble(-17-nextCoupDate.AddDays(1).DayOfWeek)); default: return(nextCoupDate); } }