Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
warm-up for backtests?

Quantopian folks,

Would it be feasible to add a function that would allow users to trigger the start of the backtest? For example:

def handle_data(context, data):  
    if cold:  
        return

    start_backtest()

    # rest of code  

The performance tracking and reporting would be triggered by the first call to start_backtest().

Grant

3 responses

I have the strong feeling that our initial implementation of warmup was wrong. We should never make you "wait" for warmup - we should always do it behind the scenes.

What do you think about, if instead, you just never had to worry about warmup? You set the start date of your backtest, and we hit that date with everything all warmed up already? That's what we're doing with live trading and paper trading, and it's one of those things that in retrospect, we realized we should do it for everything.

Make sense? Or is there another benefit to start_backtest()? Thanks.

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.

Hello Dan,

Not sure...I'll have to think about that one. I typically use the batch transform, which returns None until the trailing window is full, so the logic I outlined above would work fine. The built-in transforms (e.g. mavg) would require some additional coding, since they start returning values immediately (which has thrown off more than one algorithm, I bet).

I don't know how you do the warm-up for live trading and paper trading, so it's hard to think of use cases that would be problematic. How do you figure out how far back to start warming up? What is the trigger for the start of logging the performance?

Yes, it'd be nice not to worry about warm-up, but perhaps there is a hidden downside by doing it in the background? One concern is that if I have built-in or batch transforms within conditional logic, wouldn't there be a risk that the warm-up would be incorrect? Or do you somehow sort out the maximum warm-up period ever possibly required?

Grant

Grant the trading window should be full at warm up if Dan's adjustment was made. I've also been working on a "pause" function where the backtest buys the benchmark until after nth_day.

def pause(nth_Day, mycontext, mydata):  
    if mycontext.timestep == 1:  
        nshares=math.floor (mycontext.portfolio.cash / mydata[mycontext.SPY].price)  
        order(mycontext.SPY,+nshares)  
#        log.info("First timestep and paused. Ordering "+str(nshares)+" of SPY.")  
    if mycontext.timestep < nth_Day:  
        return(0)  
    elif mycontext.timestep == nth_Day:  
        #Liquidate position  
        liquidate_position(mycontext.SPY,mycontext)  
        return(1)  
    else:  
        return(1)  

Note that my function is still in development and does not perfectly track the benchmark during the "paused" period due to 1) the bechmark is S&P 500 not SPY, 2) commission, 3) slippage.