Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
New to Quantopian and got a couple of questions

Hello, I'm new to the Quantopian community and think this is a very interesting website with a lot of potential.

I have a few questions which are not covered by the FAQ or the documentation help provided on this website. I would appreciate any answers I could get.

1) When an order is placed at a certain price but the following bar that price does not trade, what happens to the order? Does the order persist over multiple bars or if it is not executed on the bar directly after the order is placed, is it cancelled? If it does persist over many bars, is it necessary to cancel the order if the entry signal is no longer valid? If it is necessary to cancel the order, how do you do it?

2) If I open a position but I intend for the stop loss and exit prices to change over time, would I need to program conditions for a counter position to be taken at those prices or is it possible to edit the open position (e.g in pseudo code: open_position.stop_loss = new_sl_price).

3) Is there a convenient way to pair trade multiple instruments? Would it be a better idea to write my own class to deal with the internals of it? Is there any chance someone might be able to give me some example code of how this could be done in Quantopian? Even non-functioning or partially completed code would be great. I just want an idea of how this might be achieved.

Although I have experience in python, I am still learning the API so go easy on me :) No doubt I will have a few more questions in the near future but when I get to the point where I don't suck so much I plan to share some of the algos I make.

4 responses

Hi Swarvy,

Glad you're here! I think I can answer a few of your questions.

As of now, you can place an order with no stop or limit price specified, with either stop price or limit price specified, or with both specified. If you don't use stop or limit price, then you will buy the number of shares specified at the best price you can. If the price goes up between the time you place the order and the time the order is completely filled, then you might end up paying more on average than the price at the first order.

If you include a limit price, then whenever the price of the stock is at or better than the limit price, your order will be placed. So if it's a sell order, whenever the price is equal to or higher than your limit price, you will sell as many shares as you can, up to the number of shares specified. If it's a buy order, it's whenever the price is equal to or less than your limit price.

With a stop price, it doesn't do anything until the price of the security breaks the barrier set by your stop price. If you're not familiar, here's one way people often use stop orders:

Buy 100 shares of stock X at price P. Set a stop order to sell 100 shares of stock X at 90% of P. This means that if the price of X ever falls below 90% of what I paid for it, I will exit the position by placing a market order to sell 100 shares of stock X at the best price I can get. Theoretically, this limits your loss on X to just 10% of what you initially paid for it. (You should note that in the real world, this doesn't always hold true. Prices can move discontinuously, and the price can go from P one minute to 50% of P the next minute as everyone responds to some bad news. Or prices can fall too quickly for your broker (even an electronic one!) to respond fast enough. It might hit 90% of P, but by the time the sell order is totally filled, the price is down to 70% of P).

You can also do a stop order with a buy order. This would usually be in the situation where you are short the stock in question.

The final option is a stop and limit order. This is similar to a stop order, but when the price breaches the stop price, it converts to a limit order instead of a regular market order.

Limit orders and stop orders do not go away if they are not filled. From the help doc:

All orders are good-til-cancelled, except for algorithms that are connected to a brokerage. Orders placed with a brokerage (both paper trading and real-money trading) are cancelled at end-of-day. In the future we will most likely change backtest order behavior to also cancel on end-of-day, to make the backtester more accurate.

To answer your second question, I believe that since Python doesn't have the notion of private variables or functions, you could go and change the stop or limit prices on an existing order. But I'm going to guess that you probably want to just cancel the order and place a new one at the desired price. Though I could be wrong.

There have been a few algorithms shared based on pair trading. I'd use the search feature and check some of them out!

Hello Dominic,

I've attached some code that illustrates one approach to your pairs trading question. It starts by listing the pairs like this:

def initialize(context):  
    # GLD & GDX, PEP & COKE  
    context.pairs = [sid(26807),sid(32133),sid(5885),sid(1753)]  

Then a trailing window of price data is obtained with the batch transform:

@batch_transform(refresh_period=0, window_length=W_L) # set W_L above  
def get_prices(datapanel,sids):  
    p = datapanel['price'].as_matrix(sids)  
    return p  

I found a handy function to break up the matrix of prices into pairs:

pairs = np.hsplit(prices,2) # paired prices in a list of ndarrays  

So, in the end, you have a list of the pairs, ordered as they are in context.pairs.

Hopefully, this will get you going. The attached backtest was run on minute data, with the trailing window updated every minute. It will also run on daily data (with the trailing window updated every day). I suggest working with minute data, since live trading (paper/real money) only runs at the minute level; daily bars are not available.

Grant

Hello Grant & Sam,

Thank you for your input, it has been very useful and I can tell that I'm barely scratching the surface of what can be done on this website.
In my opinion, the best way of learning something is to do it yourself, so I started with the sample algo and started writing my own basic version. It doesn't work, and even if it did, I doubt the results are very good. I've now got a few more questions (as I promised in my first post).

import numpy as np  
import math

ORD_DECAY_TIME = 5        # Defines how long an order can sit around without being filled

def initialize(context):  
    # Define the security which we will run the backtest on  
    context.spx = sid(26578)    # For now this sid is actually google  

  # In these two lines, we set the maximum and minimum we want our algorithm  
  # to go long or short our security.  You don't have to set limits like this  
  # when you write an algorithm, but it's good practice.  
    # context.max_notional = 20000.0  
    # context.min_notional = -20000.0

def handle_data(context, data):  
    # Get a list of currently open orders  
    open_order_dict = get_open_orders(context.spx)  
    # Cancel some old ones - make sure any rogue orders aren't filled  
    for order in open_order_dict:  
        if data[context.spx].datetime + ORD_DECAY_TIME > order.datetime:  
            cancel_order(order)  
    # Calculate the average price of the last day of trading  
    avg_cur_price = 0.25*(data[context.spx].open_price + data[context.spx].high + \  
                          data[context.spx].low + data[context.spx].close_price)  
    # Calculate the standard deviation of the prices  
    std_dev = data[context.spx].stddev(30)  
    record(avg_price = avg_cur_price)  
    if context.portfolio.positions[context.spx] == None:  
        if std_dev != None:  
            order(context.spx, +100, limit_price=avg_cur_price - std_dev, \  
                  stop_price=avg_cur_price - 2*std_dev)  
            log("Trade Entered: " + data[context.spx].datetime + \  
                ". Price: " + avg_cur_price - std_dev)  
    else:  
        order(context.spx, -100, limit_price=(avg_cur_price + std_dev)) # This is a problem  

The last line of code gives a runtime exception - Runtime exception: UnboundLocalError: local variable 'order' referenced before assignment. I've seen this error before in the context of variables used out of scope but in the context of the function 'order' (from what I can tell, is available everywhere in the script), I'm a bit confused. Also, why didn't the first call to this function give rise to an exception?

Question 2. In the code sample I wrote, I had a few lines at the start of the handle_data function which dealt with any out-of-date orders which were left hanging around. Judging from some of the algos people have shared on this site, most people here seem to avoid this issue by using market orders. I realise that using market orders runs the risk of getting a worse price while limit orders run the risk of not getting fille and 'missing the move'. What would more experienced algo developers recommend? What is your preference? If you prefer limit orders, based on your experience, what is the best way to stop rogue orders being filled?

Hello Dominic,

Please see attached. I've fixed the errors rather than really think about what the algo is doing. Your run-time error was caused by using order as a variable name in the 'for' loop.

P.