RubyRuby, 137 134 130130 129 bytes
Recursive function that returns the string. I'm trying to golf down the numeral encodings a bit more if possible, but I'm not sure how.
Whoops, it's practically a direct port of @Neil's ES6 answer now.
f=->x{(x<t=1e3)?"CM900D500CD400C100XC90L50XL40X10IX9V5IV4I1".gsub(/(\D+)(\d+)/){v=$2.to_i;s=x/v;x%=v;$1*s}:"(#{f[x/t]})#{f[x%t]}"}
f=->x{(x<t=1e3)?"CM900D500CD400C100XC90L50XL40X10IX9V5IV4I1".gsub(/(\D+)(\d+)/){s=x/v=eval($2);x%=v;$1*s}:"(#{f[x/t]})#{f[x%t]}"}