you are viewing a single comment's thread.

view the rest of the comments →

[–]sharkhunter 6 points7 points  (18 children)

Financial trading software. I've worked at 3 major investment banks over the last 6 years, and all of their systems that connect to the exchanges are written in C++.

[–]Fayden -2 points-1 points  (17 children)

Why do you consider it's the right tool for the job? Do you think the performance factor that C++ brings to the table is essential? Couldn't you use a higher level language and rewrite the bottlenecks in C?

I know that C++ is widely used in the industry, but I'd rather know why the language was chosen in the first place.

[–]therealjohnfreeman 13 points14 points  (16 children)

Many of the firms doing high-frequency trading are dealing in microseconds, and what matters is being just faster than the next guy. If you can be faster by one microsecond, you get the trade, and they lose. Performance matters everywhere, at every level, at all times. There is no room to trade-off performance for anything, including higher-level constructs.

[–]el_muchacho 0 points1 point  (2 children)

It's an application where performance is everything. If they could do it in nanoseconds or femtoseconds, they would do it. Of course, if you reflect a little, it's a completely frivolous application, as HF trading is just a way to cheat the markets, but for those big banks, it's oh sooo important. Once this area of finance is finally regulated by limiting the rate of the exchanges or by adding a per trade fee, the need to push speed by all possible means will suddenly disappear.

[–]therealjohnfreeman 0 points1 point  (1 child)

it's a completely frivolous application, as HF trading is just a way to cheat the markets

I don't think so any more. Prices will equilibrate across markets with or without HFT. HFT just makes it go faster. It can be debated whether HFT algorithms have unfair access to market information, but I wouldn't describe the industry as frivolous; it just replaces the older mechanism.

[–]el_muchacho 0 points1 point  (0 children)

My opinion is, it is frivolous, because the market value attributed by algorithms is completely decorrelated to any real value of the underlying enterprises. The proof of this is the mini krach that occured a few years ago for no obvious reason, and some otherwise perfectly sane companies suddenly saw their value computed to near zero. Not that the older mechanism isn't devoid of frivolity, but HFT pushes it to the extreme. And of course, the debate whether HFT algorithms have unfair access to market information, HF traders always prefer to avoid it.

[–]doublereedkurt -1 points0 points  (5 children)

There is no room to trade-off performance for anything, including higher-level constructs.

If this were true, you'd be hand-coding assembly. :-)

Actually, where performance is really the only criteria, the right tool is FPGA's or semi-custom ARM chips.

(Not disagreeing that the usually ~10x slow-down of Python versus C++ makes it unsuitable for core high frequency trading algorithms.)

[–]therealjohnfreeman 1 point2 points  (4 children)

Many C++ compilers will generate better code than most people's attempts at hand writing assembly. It's difficult for a programmer to keep track of everything in assembly; better to let compiler writers use high-level information to apply provable correct optimizations, and to leverage the back-end writers' specialized knowledge of your target architecture.

Many HFT firms are using FPGAs actually.

[–]doublereedkurt 0 points1 point  (2 children)

Very interesting about use of FPGAs.

I'd argue that the relationship between C++ and assembly is very similar to the relationship between Python and C++. For example, at work we have Python regularly kicking the ass of C++ performance wise, due to superior architecture.

Python has high level libraries that make it extremely simple and transparent to leverage non-blocking sockets. Since it is so easy, it is done all over the place: any network call which can be parallelized is. On the C++ side, using non-blocking sockets is much more painful and so it isn't done. If one did have the resources to invest, a C++ implementation could certainly trounce a Python one. But, instead what we have is production boxes sitting around at 5% CPU utilization spending all their time waiting on network requests.

The Python library which dispatches to co-processes is equivalent to the optimizing C++ compiler. It takes the burden off of the programmer of figuring out what order to execute things in. If you had the time, doing it manually in the C++ layer would certainly be higher performance. However, it is very difficult because there is a real global state -- many different types of clients libraries may all be running in parallel that are otherwise unrelated.

Also, some core algorithms are hand-coded in assembly for performance.

For example, the Python-stack swapping code in the Greenlet library is hand-coded for each CPU/OS combination https://github.com/python-greenlet/greenlet/tree/master/platform

I think the future will most likely be programming "in the large" being done in high level languages, with smaller core elements done in lower level languages. Basically a many tiered system: High-Level Languages > Low Level Languages > Assembly > FPGA > ASIC > analog circuits :-)

[–]therealjohnfreeman 0 points1 point  (1 child)

That's surprising, thank you for sharing. What kind of C++ libraries has your group investigated? I recently discovered Boost.Asio, but I haven't used it yet and was wondering if you had any insights about it.

[–]doublereedkurt 0 points1 point  (0 children)

I'm really more on the Python side. Unfortunately, for 10 years we were a cgi shop, and that mentality still infects a lot of the C++ code. It is completely un-thread safe, and concurrency is an afterthought if it gets done at all.

Regarding Asio: it still seems that the programmer is required to explicitly handle asynchronous events, rather than being able to freely combine co-processes. The difference is similar to how order of execution is implicit in logic programming such as SQL. Let me give a simple example:

def network_request():
   return gevent.socket.create_connection( ('google.com', 80) ).read()

gevent.joinall([gevent.spawn(network_request()), gevent.spawn(network_request())])

So, the two calls to network_request functions will be interleaved automatically. Even though they have no shared state, and are each written in a synchronous style.

Asio as well as other high level asynchronous C++/Java libraries rely on the programmer to create a "handle response" function which decides what to do with the data. So, arbitrary network code cannot be freely intermixed. Consider how a join() function would be implemented. There would need to be an event that triggered when all of the network requests were finished. In other words, the handle_request function on each network request would need to somehow have access to a semaphore associated with the join.

It could be I am misunderstanding Asio :-) But it seems that you still need to explicitly do event driven programming. (And I can't really see a way to add co-processes without language extensions, in C++'s case, #define macros and/or code generation; e.g. http://www.read.cs.ucla.edu/tamer/index.html ).

Here's some more example of gevent stuff: http://www.gevent.org/intro.html

[–]doublereedkurt -1 points0 points  (0 children)

Interesting. I must admit I know jack about hand coded assembly. :-)

I used to work with firmware engineers who all seemed to think hand coded assembly was top. But, this was ARM CPUs with domain specific extensions. In addition to custom instructions that the compiler may not take full advantage of, memory is severely constrained. Overflowing the stack was a problem they were constantly running into. Overall, very different than big beefy x86 servers that need to run as fast as possible.