/// <summary>
        ///
        /// </summary>
        /// <param name="referenceDate"></param>
        /// <returns>e.g "Z8"</returns>
        public override string GetNextAbsoluteMainCycleCode(DateTime referenceDate)
        {
            int    referenceYear     = referenceDate.Year;
            int    referenceMonth    = referenceDate.Month;
            string absoluteMonthCode = FuturesMainCycleCodes[referenceMonth - 1];

            //  check if adjustment required
            if (referenceMonth % 3 == 0)//check if need to advance to next code
            {
                DateTime unadjustedExpirationDate = RuleHelper.LastDayInMonth(referenceMonth, referenceYear);
                if (referenceDate >= unadjustedExpirationDate)//if option expires today - move to next code
                {
                    if (referenceMonth == 12)
                    {
                        referenceMonth = 1;
                        ++referenceYear;
                    }
                    else
                    {
                        ++referenceMonth;
                    }
                    absoluteMonthCode = FuturesMainCycleCodes[referenceMonth - 1];
                }
            }
            return($"{absoluteMonthCode}{referenceYear % 10}");
        }
        /// <summary>
        /// Gets the last trading day.
        /// </summary>
        /// <param name="month">The month.</param>
        /// <param name="year">The year.</param>
        /// <returns></returns>
        public override DateTime GetLastTradingDay(int month, int year)
        {
            //Rather than the last weekday, this use the last day for IB contracts
            //since the RBA dates are very close to the beginning of the month.
            DateTime significantDate = RuleHelper.LastDayInMonth(month, year);//LastWeekdayDayInMonth

            return(significantDate);
        }
        /// <summary>
        /// IRH7,IRZ9 (90 day futures)
        ///
        /// IBH8,IBU9 (30 day futures)
        /// </summary>
        /// <returns></returns>
        /// <param name="referenceDate">
        /// if 2000, IRZ8 is futures that expires in December 2008.
        /// if 2010, IRZ8 is futures that expires in December 2018.
        /// </param>
        public override DateTime GetLastTradingDay(DateTime referenceDate)
        {
            var      month = (int)LastTradingDayHelper.ParseToCode(CodeAndExpiryMonth.ImmMonthCode);
            DateTime unadjustedExpirationDate;

            if (CodeAndExpiryMonth.Year < referenceDate.Year % 10)
            {
                int realYear = referenceDate.Year - referenceDate.Year % 10 + CodeAndExpiryMonth.Year + 10;
                unadjustedExpirationDate = RuleHelper.LastDayInMonth(month, realYear);
            }
            else
            {
                int realYear = referenceDate.Year - referenceDate.Year % 10 + CodeAndExpiryMonth.Year;
                unadjustedExpirationDate = RuleHelper.LastDayInMonth(month, realYear);
            }
            return(unadjustedExpirationDate);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="referenceDate"></param>
        /// <returns>e.g "Z8"</returns>
        public override string GetNextCode(DateTime referenceDate)
        {
            int    referenceYear     = referenceDate.Year;
            int    referenceMonth    = referenceDate.Month;
            string absoluteMonthCode = FuturesExpiryCodes[referenceMonth - 1];
            //  check if adjustment required (if it is already e.g. 20th of the March - the March futures has already expired)
            //
            var unadjustedExpirationDate = RuleHelper.LastDayInMonth(referenceMonth, referenceYear);

            if (referenceDate >= unadjustedExpirationDate)//if option expires today - move to next code
            {
                if (referenceMonth == 12)
                {
                    referenceMonth = 1;
                    ++referenceYear;
                }
                else
                {
                    ++referenceMonth;
                }
                absoluteMonthCode = FuturesExpiryCodes[referenceMonth];
            }
            return($"{absoluteMonthCode}{referenceYear % YearsInDecade}");
        }