Inevitably bugs like this crop up when you have half a dozen minor things all wrong. Fixing one of them may actually make the others seem worse, so it's easy to run around in circles for weeks without making any real visible progress.
What you need to do at this point is break things down as far as you can. I don't know your code obviously, but here's how I'd go about getting the problems fixed:
- Define your simulation model on paper - how it should work ideally
- Nail down all your theoretical edge cases and stuff in your head first, so you know what the target looks like
- Reduce this to a set of implementation steps
- Break down each step into the logic components needed to accomplish it
- Break it down further
- No, really, you're still thinking too big.
- Once you have a list of extremely tiny (think 2-3 line of code) operations, it's time to debug them
- Unit test everything you possibly can
- Collect shitloads of data on the behavior of everything you can't effectively unit test
- Go back and unit test a bunch of that stuff anyways because you really can and it just seems ugly
- Your guiding principle at this point should be that you can prove that, in isolation, any one of your moving parts is doing its job correctly. The up-front theory work is mandatory, because it does no good to combine a bunch of working parts into a whole that does the wrong job.
And so on.
This can easily seem insurmountable but it's just a matter of disciplined engineering to get it done. In the end it's better for you guys as developers to tackle this yourself instead of shelling out to another programmer to do the grunt work. You already know your goals better than any outsider, and you know what your expectations are. Just establishing that would run you up several grand in consulting fees if you brought in someone new.
Learn to love Excel and dozens of megabytes of log data; and remember, break it down into tiny parts. You'll be fine :-)