My current project has me exercising a number of financial formulas on security and benchmark data. I have 2 – 3 sets of data which based on their type (benchmark or not) have varying calculations which set similar properties. I won’t bore you with the details, but the calculations do require more than the four basic math operators. In addition, the sets are dependent upon each other. For example, a start date common to each set needs to be determined and, in cases, benchmark results are leveraged in non-benchmark sets.
Along with a test application, I’m going to be handing my code off to other developers and I really want the transition to be as seamless as possible. To help out with this, I have spent some time creating my component in an intelligent, easy-to-use manner. (What? I don’t always do this?) For example, I’ve opted to have my component simply accept whatever raw data is available. The component will “clean” the data, determine the number of sets and types and process. Most importantly, the results will then provided back using datatypes which I think are most suitable for consumption by the calling application.
I like the current architecture, but I had reservations with the way the calculations were coded. As it turns out, a few of the calculations require the exact same logic. For example, Formula A and Formula B might each loop through the last 10 years of quarterly return data. Obviously, this had me wanting to combine some of my routines. But as I refactored and refactored and refactored, I found my code was getting more and more and more obscure. The logic was very difficult to understand (never mind read) and I wasn’t comfortable handing it off to others.
I’ve rolled back my refactored code. I’ve blatantly abandoned refactoring in this case. Instead, I’m keeping the code in logical blocks which I believe will aid in learning, extending and (gasp!) troubleshooting the component in the future. Though I’m sure there would have been performance gains if I were to continue down the refactoring path, I’ve convinced myself that they would be subtle. Perhaps I could have added ample (read: lots and lots) comments to accompany the obscure, refactored code, but I don’t think good code requires such measures.
I’m happy with my decision. Now it’s time to finish up, hand off the code and wait for the new owners to laugh at its poor quality — of which they will hopefully understand and be able to manage every line. We’ll see.
I should mention, I will be reworking some of my code. Do yourself a favor. If you know you are going to be performing anything other than basic math, don’t use decimals. Use doubles instead. Thanks to functions like Math.Pow() and Math.Sqrt(), I’ve been casting my brains out over the past couple of days and it is time I bite the bullet and change my datatypes.