“Isn’t April Fools over?” the very first thought running through your mind after glancing at the title. Rest assured, this is not a trolling post to make a fool out of you. This year’s April Fool post is here, in case you missed the once-in-a-lifetime C++ joke of its kind. This article is about slowing the trading frequency of HFT to yield more profits, and the later section discusses lock-free versus block-free.
In High-Frequency Trading (HFT), orders are made as soon as possible before the ‘best’ price disappears. In the olden days, when HFT was rare, it was true. However, in today’s market, where HFT is very active, and once a market trend is detected, it is heavily reinforced by many HFT players. This is why circuit breaker was introduced in stock markets around the world in the late 2000s to stop the stock price from driving south temporarily. When a trend is unstoppable (in upward trend), the longer the wait before putting a sell order, the more significant the difference between your current holding price and the future selling price.
In Medium Frequency Trading (MFT), market data is also processed in low latency to facilitate quick trading decisions. In the long trade, the market maker can afford to wait before making a sell order, and likewise, in the short trade, wait before buy order. If the hard choice for strategy comes between long trade and short selling, always go for long trade because in the latter, the loss could be unlimited when the market moves against you (after the circuit-break period). More earnings are reported in today’s market dominated by HFT, but the average profit on each trade is lesser. Also, HFT means more payments from profit go to the transaction fees. MFT means less transaction fees.
In firms that are in HFT business, its developers favor lock-free data structures but the cases against lock-free are
- It is very, very hard to get right.
- It drains the laptop battery quickly and laptops are very scalding hot at 100% CPU utilization, kicking in the fan spinning at full speed, draining the battery even quicker.
- It is wasting CPU cycles that other processes could use to do valuable work. It slows down the other threads and processes.
- It is not portable to a different processor architecture such as ARM.
- It ignores the fact the CPU frequently sleeps in between milliseconds. Remember the controversial decision of Google Chrome team to run timer at one-millisecond interval?
- It is useless to spin in the user-mode thread where an OS scheduler can preempt your thread from execution anytime without you knowing. Acquire a mutex to inform OS that thread is waiting on it so that OS wakes up the thread as soon as the mutex is unlocked.
My advice? Don’t single-minded tracked focus solely on performance just for the sake of it, and you’ll find yourself missing the woods for the trees. The better alternative out there is block-free (also known as share-free). Whatever name lock-free is given, it is still essentially blocking.
To achieve block-free, sharing should be reduced if not eliminated. Make the read-only copies of the data and if modification is unavoidable, make new objects of modified data. What if only serial access to data is permitted and no copies are allowed?
Take this simplified example of when your program has to talk to 4 servers with 2 threads on a dual-core processor? Each of the 4 servers is bound to its data structure that requires serial access in your program. When the data packets arrived and dispatched randomly, at any one time, two threads could very well be processing packets from the same server, and this situation requires a mutex lock to prevent data corruption and needless to say, performance degradation. Lock can be eliminated when the data packets from each server are always dispatched to their own assigned thread, meaning packets from the first 2 servers go to the first thread and the other 2 to the other thread.
Block-free has its challenges. It is more difficult to achieve block-free within the program constraints than to use lock-free data structures. Block-free is the far superior option to lock-free. So always block-free whenever possible!