I'm trying to think of the best way to create a function that avoids using loops/while. Any ideas?
Given a function prototype:
{[sd;n:hols]
/ return list of n number of dates <= SD, excluding weekends and hols
}
Thanks and happy holidays
I'm trying to think of the best way to create a function that avoids using loops/while. Any ideas?
Given a function prototype:
{[sd;n:hols]
/ return list of n number of dates <= SD, excluding weekends and hols
}
Thanks and happy holidays
You can use lists and the fact that dates in kdb+ are built on underlying integers:
{[sd;n;hols] d where not[d in hols]&1<mod[d:sd-til n]7}
This uses a til
to generate the list of dates up to today, then filters using mod
and at the same time checks to make sure the remaining dates aren't in the holiday filter list, before using true results to index back into the generated date list. These will be in descending order, but you can use
{[sd;n;hols] reverse d where not[d in hols]&1<mod[d:sd-til n]7}
To have an ascending date order.
An alternative solution would exclude the holidays before calculating the modulus:
{[sd;n;hols] d where 1<mod[d:except[;hols]sd-til n]7}
The components here are similar to Ryan's answer, other than using "except" to exclude the holidays.
In order to extract exactly n days, you can initially generate a larger list and return a sublist of the correct length, e.g.
{[sd;n;hols] n#d where 1<mod[d:except[;hols]sd-til 2*n]7}
knowing 2000.01.01 and 2000.01.02 are Saturday and Sunday and that mod those dates are 0 and 1 then excluding all dates who's modular is 0 1 I used:
getBusinessDays:{[Dates;N;Hols] N#(Dates*(Dates mod 7) in 2 3 4 5 6) except 2000.01.01,Hols}
Will return the first N business days you entered excluding holidays you chose.