Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Trouble with Time Resttictions on purchases

I was trying to write a "simple" restriction on ordering time. Specifically, I tried to prevent any orders in the first few minutes using

    context.hour = get_datetime('US/Eastern').hour  
    context.minute = get_datetime('US/Eastern').minute

    if (context.hour = 9) and (context.minute < 33):  
        order(sid(24), 50)  

On the first day it works. On every subsequent day it orders at 9:31 (not what I expected), skips a few minutes (as I would expect), and then orders every minute (again as expected).

Why does it order at 9:31 ???

11 responses

In your order execution you use (context.hour > 9) or (context.minute > 33): when using the or operator you are saying that if either choice is True go for it, and since the hour will always be greater than 9 it will always trade. Switch that or to and and see how things turn out. That being said this will only trade during the last 27 minutes of the day because both the hour must be greater than 9 and the minute greater than 33.

Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.

@Timothy:

Here is another idea you can use:

def initialize(context):

    # Used to prevent trading at start and end of day  
    context.stop_trading = True

    # Don't trade the first and last 10 minutes of the market day  
    schedule_function(start_trading,date_rules.every_day(),time_rules.market_open(minutes=10))  
    schedule_function(stop_trading,date_rules.every_day(),time_rules.market_close(minutes=10))

def start_trading(context, data):  
    # This is used to start trading 10 minutes after open  
    context.stop_trading = False  

def stop_trading(context, data):  
    # This is used to stop trading 10 minutes before close  
    context.stop_trading = True

def handle_data(context, data):  
    # Don't hold any positions the first and last 10 minutes  
    if context.stop_trading == True:  
        for stock in data:  
            # Sell everything  
            order_target_percent(stock, 0)  
            print("{0} {1}: CLOSE order".format(get_datetime().time().strftime('%H:%M:%S'),stock.symbol))  
            # Stop processing this minute  
            return  

I think you missed my point, James, so let me be clearer.

The code now reads

   if (context.hour > 11) or (context.minute > 55):  
        order(sid(24), 50)  

Before noon, this should trade only for the last few minutes of each hour. After noon, it should trade every minute.
On the second day of the back test (and all subsequent days), the Transaction Details for the backtest of this code records trades at:
9:31
9:57
9:58
9:59
10:00
10:57
10:58
10:59
11:00
11:57
11:58
11:59
12:00
... and then every minute for the rest of the day

The problem is the very first trade of the day. 9:31 AM is NEITHER hours > 11 NOR minutes > 55 and yet a trade is executed. You can't stop that first order of the day this way!

I figured out I could fudge my way around this with the code:

if context.hour == 16:  
    pass  
elif (context.hour >= 12) or (context.minute > 55):  
    order(sid(24), 50)  

Apparently there is some bug that orders from the previous day ARE carried over to the next day. That would explain why the very FIRST day never had the order at 9:31. So by forcing the code to "PASS" at 4:00 PM the previous day, that opening order is NOT carried over.

Tristan, that may well work, but it is a complicated solution to a simple problem.

I am starting to suspect that Quantopian will simply not work for what I want. I really would like it to work so I can port over some ideas from a spreadsheet algorithm, where I seem to average well over 30% per year for the last 20+ years (trading just SPY, so slippage, liquidity, etc should not be serious issues.)

Trades at the open and close are a key part of the strategy I developed -- in large part because Open & Close numbers are freely available from several sources. Quantopian doesn't support Market On Open or Market On Close; now it seems that it can't easily handle even the first few minutes of the day. Taken together, this makes Quantopian an awkward platform for my work.

PS. James, you said "since the hour will always be greater than 9". That is incorrect. from 9:00 - 9:59, the hours is 9, which is not greater than 9. Hence no trades at all should occur until 9:34, at which point trades should run the rest of the day. (I did double-check that logic a couple times.)

I bet the reason you get that 9:31 AM trade is because you are submitting a trade the very last minute of the market, but it is not processed until the next day. If you stop trading a few minutes before close, you should not see the 9:31 AM trade.

You're right I miss typed.

Here is an framework I put together for you, is this more along the lines of what you are trying to do? Clone it and examine the print output.

@ Tristan makes a good point as well

I appreciate the efforts to help, but they are not really solving the root problem. They are "treating a symptom, but not the disease."

1) Several other discussions have highlighted the fact that Quantopian closes all orders at the end of the day. Hence there should not be any order "waiting" first thing in the morning. Hence there should be no need for some code to block that order.
2) I don't want to stop a few minutes before the end of the day -- I want to trade the very last tick (ie on market close).
3) James' sample code never generates any trades. The log has lots of lines printed at appropriate times, but no trades are actually placed.

What I really want is something like ...

Calculate some Open_Criterion before trading starts.  
If Open_Criterion = true  
    execute an order on market open.

Calculate some Daily_Criterion during the day  
If Daily_Criterion = true  
    execute an order during the day

Calculate some Close_Criterion near the end of the day  
If Close_Criterion = true  
    execute an order on market close  

So simply forcing the algo to skip a few minutes at the start and close is NOT useful. As I said, since Quantopian can't do Market-On-Open and Market-On-Close orders (and also can't seem to handle the first and last minutes well), it is most likely not the platform for me -- no matter how clever we try to be about excluding the first couple minutes or the last couple minutes. :-(

We have had a lot of requests for MOO and MOC orders and every time someone mentions it it becomes more important, in the mean time here is a thread that attempts to replicate MOO buy leveraging our custom slippage model.

I'd like to clarify a few things...

  • Quantopian does not close orders at the end of the day during backtesting, or paper trading. In live trading with Interactive Brokers, orders do get closed at end of day.

  • As the Quantopian backtester executes orders at the end of the next bar of data, placing an order at 1559 (or one minute till market close) will lead to the order trying to be executed at 1600. That's as close to last tick that you can get on Quantopian, we provide free minute and daily level data.

  • As you said my code prints at the appropriate times, replace my print statements with your order statements and then it will start placing trades.

Apologies for the confusion, datetimes are some of the hardest things to work with in programming and even more so in finance where they are extremely important.

Good luck

Thanks for all your time James, and for the clarifications.

I can appreciate that properly dealing with time -- especially right at the beginning or end -- could be a programming nightmare. For a free platform, Quantopian is really quite remarkable. Unfortunately, it just doesn't seem like the best platform for me.

@Tim -

We all agree that Q has limitations, some bigger than others. But they have been consistently adding features and scalability, so I expect them to continue to improve.

Regarding real live trading, Q does not focus on that aspect anymore. I hope they keep that feature around so that we can invest in our own algos, but I also like the fact that Q can "rent" my algos (if they are good enough) to be used in a large hedge fund!

I hope you will keep testing and providing feedback to the community!

Cheers,

Tristan