I think I'm fairly close to a working flurry closed form expression.
There are three attacks which can proc flurry, white crits, stormstrike crits and wf crits, the latter two don't consume charges.
So if we assume an already flurried attack, we modifiy the 3 swings to add wf and ss
The attack speed is basically
attackspeed = (ws1 + ws2) / (4 * 1.3f * (1 + haste / 100));
for two 2.6s weapons and 0 haste this is obviously 1.0s (e.g. we swing each second)
Now we do two SS attacks each 10s, so during our flurry time of 3 swings, we basically have:
ssinthree = 3 * attackspeed / 5;
wfprocprob = 0.36f
Our percentage of time, in which we can actually proc wf is defined as:
The expected time to proc WF (which is attackspeed/0.2f basically) divided by the expected time + cooldown:
wftime = (attackspeed / (wfprocprob / 2f)) / ((attackspeed / (wfprocprob / 2f)) + 3);
This basically means, that faster weapons actually increase the percentage of time, in which we can't proc windfury, basically if we expect a wf proc every 3s and have a 3s cooldown after each wf proc, the percentage is 50% (should be fine so far)
Now we add to our 3 flurry swings, the probability not to have no wf proc at all (1-(1-0.4)^(wftime*3) and our percentage of stormstrike swings in 3 normal swings.
flurryprob = (float)Math.Min(1 - Math.Pow(noncrit, 3f + 1 - Math.Pow(1 -wfprocprob, wftime * 3) + ssinthree), 1.0);
So for two 2.6s weapons, no haste = 1.0s attackspeed and a 20% wf proc rate (simplified in this example), we expect a wf proc every 5s, so the actual time we spent in "trying to get wf" is 62.5%, our ss percentage of swings is 0.6, together with 30% crit this results in:
1-(1-0.3)^(3+1-(1-wfprocprob)^(0.625*3)+0.6) = 0.77%, e.g. our flurry probability is 77%
Technically this is still not 100% correct, since stormstrike is actually more a spike (discrete) value, than a continous value. But it should do fine for now.
Some real life values I gathered:
Two 2.6s weapons, 28% crit I had on the ptr an uptime of 73%, the algo calculates (with reduced 0.36f wfprocprob) of 74.7%. Most of the difference is probably that I didn't spam Stormstrike properly
It is still not 100% perfect, but is fairly correct for usage in closed form expressions.