3

I'm calculating, say, NASDAQ, index.

All stocks prices are decimal I can make weight decimal or double - it doesn't matter.

nasdaq = weight1 * stock1 + weight2 * stock2 + .... + weightn * stockn.

As stock price is decimal it seems it makes sense to make nasdaq index decimal. But i do not want to recalculate nasdaq index every time some stock is updated. Instead I want to "cache" previous value and then only calculate difference. For example if stock2 is changed, then:

stock2OldPrice = stocks[2];
diff = stock2 - stock2OldPrice
nasdaq += diff * weight2     // need to synchronize
stocks[2] = stock2

Now I need to synchronize nasdaq index because stocks can be updated at the same time. For example I can receive in parallel threads new price for MSFT and INTC. So I have to write Interlocked.Add(ref nasdaq, diff * weight2); refer to my previous question how to synchronize addition from different threads using lock-free code? However I can not do that for decimal because decimals are not supported.

Ok, lets try to declare nasdaq index as double? With doubles I can do Interlocked.Add but now another problem: cause on every step I will convert from decimal to double I will lost precision. And then my "smart caching algorithm" will not absolutely "precise". It means that after 100 000 000 of updates value of my index become completely wrong I can't deal with that.

So it is not possible to use nor double neither decimal.

I do see only one possible solution - I have to declare nasdaq index as decimal so I can keep using my "smart caching algorithm" and so I have to use more complex "synchronization" mechanism, likely I have to use spinlocks.

Probably you can see simpler solution?

Community
  • 1
  • 1
Oleg Vazhnev
  • 23,239
  • 54
  • 171
  • 305
  • The simple solution would create a better cache solution. – Security Hound Jul 05 '12 at 15:34
  • Have you actually benchmarked this? It seems like all of the synchronization overhead is going to outweigh any potential gains from your caching system. It also obfuscates the meaning of your code. I would personally just create a STOCK type and use LINQ: nadaq = stocks.Sum(s => s.WeightedValue); – itsme86 Jul 05 '12 at 15:39
  • @itsme86 it doesn't make sense to sum everything every time when only one component is changed, right? in hft seriosly I want to do exactly as much as I have to do and not more. – Oleg Vazhnev Jul 05 '12 at 15:41
  • @Ramhound what would be better cache? – Oleg Vazhnev Jul 05 '12 at 15:42
  • I agree with @itsme86. The NASDAQ-100 index (the on most used for tracking the nasdaq) only has 100 stocks in it. Summing all those stocks would probably be faster than using spin-locks and caching. Even if you used all 2700+ stocks, it still would be pretty speedy. – Ryan Bennett Jul 05 '12 at 17:06
  • @javapowered You wouldn't sum everything every time a component changed; you'd only do it when you need the final value (i.e. several components could change between queries). You could even store the latest sum and use a "dirty" bit to indicate a component changed and the value needs to be recalculated. – itsme86 Jul 05 '12 at 21:33
  • @itsme86 using dirty bit is too expensive as I do not want to spent time to synchronize things – Oleg Vazhnev Jul 06 '12 at 07:44

0 Answers0