However, in practice, CPUMiner, for example, finds shares with difficulties ranging from 0.01 to 10.0 within a 10-minute period. As a result, our formula leads to a hashrate that fluctuates wildly (by several times), deviating significantly from the actual hashrate.
Isn't that normal? That's why the network hashrate is an estimate, and the difficulty is only adjusted every 2016 blocks.
Could you suggest a solution or at least point us in the right direction for further investigation?
Let me start by saying I'm not a Bitcoin miner, but can't you increase the time period over which you calculate the hash rate?