Anony - thanks for the helpful description a couple replies above. The only thing there that I think isn't quite right is that the last_sales_price is not continuously updated - it is essentially the same thing as the close price, but on portfolio rather than data.
Anony - The minute is being driven by Nanex's NxCore product, our datastream. Their data product is built such that they can guarantee a continuous stream of data with data that is timestamped by their servers and delivered to us in a predictable, consistent order. Basically, they are handling a lot of the data problems for us, and we just have to make sure we're getting a clean stream from them before we package it into bars.
As for the behavior when a new minute bar becomes available; We don't have a specific heuristic that decides which algo processes first. All of hundreds of live algos are distributed across dozens of servers. On a given server, each algo has its own thread. The OS of the server decides which thread to run, and I couldn't even tell you how it chooses. We watch the servers and server load and make sure nothing is CPU starved. I'm sure our implementation of this detail will change as we get larger in scale.
As for the order handling: your estimation of order handling is correct. How the messaging gets handled is reasonably complex in execution, but simply described in outcome: your algo always has the best possible information about the current state of affairs. For instance, if you place an order, it is filled in part, and then you cancel that order, your algo knows that the partial fill has happened, and it knows that the order is still opened. That order will be listed as "open" until either a) it is complete filled or b) the cancel is confirmed by IB. As you know, orders fail for many other reasons too - a short sale may fail because the broker has none to loan; insufficient funds; insufficient margins; etc. In all of these cases the order is reported back to the algorithm as "canceled."
So, how do you handle all that uncertainty? You have to be smart about your algorithm coding. Imagine this truly naive algorithm:
- Minute 1: Submit order for 100 shares of Apple
- Minute 2: Cancel order from minute 1
- Minute 3: Submit order for 100 shares of Apple
- Be astonished to find out you actually own 200 shares of Apple because order 1 was filled before cancel
This is what you should write instead:
- Minute 1: do an order_target() for 100 shares
- Minute 2: Cancel order from minute 1
- Minute 3: do an order_target() for 100 shares
- Note that you have 100 shares of Apple, exactly as you hoped/expected you would.
By doing that type of coding, where you check your state before attempting to change state rather than assuming you know the existing state, you can let Quantopian's back end deal with all of the gnarliness of order rejection, partial fills, etc.
Grant: you are correct that if your algo takes too long (50 seconds) it will get shut down. I agree there is no need to be frantic. It's just that if your algo spends 20 seconds computing, then it will be 20 seconds before your orders are issued.
I have been thinking about a way to diagram the whole thing - it's on my to-do list somewhere.