It can also be done with a while loop. (Edit: I'm not saying this is better than intervalmatch for this case, just that it's an alternative that may be better for SOME cases, so I think is worth mentioning.)
NewTable: LOAD ID ,AMOUNT ,date(VALID_FROM + 1 - iterno()) as TXN_DATE RESIDENT Data WHILE VALID_FROM + 1 - iterno() < VALID_TO ;
I'm not sure why you'd put AMOUNT on this table, though. And I would think you'd want to include VALID_TO as a TXN_DATE, but you don't appear to. If you meant to include it, just use <= instead of <. Also, I was unclear what was going on with your 1/1/5999 date. I'd normally think that means "valid forever", where you instead treated it as "only valid for the VALID_FROM date". My solution above treats it as valid forever. If you don't need future dates, make sure to put in today() as a limit as well, like by doing rangemin(today(),VALID_TO).
And if we want a calendar, we can now build it from TXN_DATE:
Calendar: LOAD * ,year(TXN_DATE) as TXN_YEAR ...etc... ; LOAD date(fieldvalue('TXN_DATE',recno())) as TXN_DATE AUTOGENERATE fieldvaluecount('TXN_DATE') ;