If you work with credit default swaps (CDS’s) it can be quite useful to have an Excel function which calculates the next IMM date from a given date. IMM dates for credit default swaps are unadjusted and fall on 20th March, June, September and December.

It’s not quite as easy to do this with native worksheet functions as you might first think, but this formula does the job quite nicely:

` =DATE(YEAR(A2),CEILING(MONTH(A2)+(DAY(A2)>20),3),20) `

The trick to this formula is the `CEILING()`

function which is being used to round the month portion up to the nearest multiple of significance of 3 – there are 3 months between each IMM date. If the date in cell A2 is an IMM date then the formula returns that date – if you’d prefer it to return the following IMM date then just change the > to a >= .

There are lots of different ways to do the same calculation in VBA. Here’s an interesting one:

Public Function NextIMMDate(ByVal dteFromDate As Date) As Date
Const lngMONTHS_PER_ROLL As Long = 3
Const lngROLL_DAY As Long = 20
Dim lngMonth As Long
lngMonth = -Int((-Month(dteFromDate) - IIf(Day(dteFromDate) > lngROLL_DAY, 1, 0)) _
/ lngMONTHS_PER_ROLL) * lngMONTHS_PER_ROLL
NextIMMDate = DateSerial(Year(dteFromDate), lngMonth, lngROLL_DAY)
End Function

The calculation method of the IMM month definitely warrants some explanatory comments. `Int()`

always rounds negative numbers away from 0 so, by negating the input into `Int() `

and then also the final output, we are rounding the number up. Factoring this in with the rest of the IMM month calculation, we have replicated the logic of CEILING() in the formula we saw earlier.

VBA does not have its own, native `RoundUp()`

or `Ceiling()`

functions: yes, you could call Excel’s worksheet function versions via the `Application.WorksheetFunction`

class, but the above approach is faster.

Here’s a little test in the Immediate Window to see if it gives the expected results:

`?NextIMMDate(#1/10/2012#)`

20/03/2012

?NextIMMDate(#3/20/2012#)

20/03/2012

?NextIMMDate(#6/12/2012#)

20/06/2012

*Edit: If you want to calculate the next ***Futures** IMM Date (ie 3rd Wednesday of March, June, September, December) then please read the comments below.

### Like this:

Like Loading...

*Related*

## About Colin Legg

RAD Developer
Microsoft MVP - Excel
2009 - 2014

Hi Col

I suppose one could achieve the same effect using the \ divide operator instead of the Int()?

Also, what plugin are you using to display your VBA?

Do you know how it is some Date functions return a serial date (formatted) and others (especially the old analysis toolpak ones) return the long integer value?

As always Colin, nice article. Nice tip on how to emulate Ceiling. Thanks :)

LikeLike

Hi Jon,

I’m using the WordPress’ SourceCode tag.

http://en.support.wordpress.com/code/posting-source-code/

It doesn’t support highlighting VBA, so I’m using VB in the language parameter. On occasions, it can be quite frustrating to use – particularly if you need to edit your post. The main thing I have problems with is code indentation; I might start posting code without indents and suggest that readers copy it into the VBA IDE and then use Stephen Bullen’s smart indenter to get it looking right. Cue another blog post…!

Nice question on Excel’s behaviour of automatically formatting dates for some “date” worksheet functions and not others. I’ll have a think and try to come up with a decent answer.

Thanks (as always) for your comment.

LikeLike

Regarding the date formatting, here’s what Mr Govert (XL-DNA) says:

http://stackoverflow.com/questions/8229039/how-to-get-excel-udf-to-return-an-actual-datetime-instead-of-general-or-double

It’s worth noting that this gives a date format:

=TODAY()

but something like this doesn’t:

=IFERROR(TODAY(),TODAY())

LikeLike

Thanks Colin. So to emulate would likely involve that timer method you once blogged. I think the user should just format the result. lol

LikeLike

Excel changes the format to a date when the formula is parsed (not when it is calculated) so a safer bet would be to use the worksheet’s change event handler. Best of all (as you rightly said), let the user do it!

LikeLike

If you want to calculate the next Futures IMM Date (ie 3rd Wednesday of March, June, September, December) then use this formula posted by Barry Houdini on SuperUser.com:

`=LOOKUP(A2,DATE(YEAR(A2),{0,3,6,9,12;3,6,9,12,15},22)-WEEKDAY(DATE(YEAR(A2),{0,3,6,9,12;3,6,9,12,15},4)))`

Note that if the date in A2 is an IMM Date then the formula returns the following IMM date rather than the date in A2.

This formula is derived from the general rule that you can calculate the Nth occurrence of a given day of the week in a given month by using:

`=DATE(Y,M,1+7*Nth)-WEEKDAY(DATE(Y,M,8-DayOfWeek))`

LikeLike

Sorry, If I am little slow, but would you get the last IMM date before the date in cell A2, for example ?

LikeLike

Hi Holger,

To get the previous CDS IMM date you could use the

`FLOOR()`

function instead of`CEILING()`

:`=DATE(YEAR(A2),FLOOR(MONTH(A2)-(DAY(A2)<20),3),20)`

If the date in A2 is an IMM date then this formula will return that date. If, in that case, you still want to return the previous IMM date then change the

`<`

sign to`<=`

LikeLike

Hi Colin,

that seems to work just fine – thank you very much for the quick solution !

LikeLike

hi Colin,

By inference, here is the formula for prior IMM date:

=DATE(YEAR(A2),FLOOR(MONTH(A2)-1+(DAY(A2)>20),6),20)

Also changed the frequency to SA is it is now the convention for CDS.

LikeLike