Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Proof-reading my Python codes and logic - just a short one :)

I have a short excerpt from a script I got somewhere and would like to clarify the logic behind it with the experts. The script comes from a program for backtesting a mean-reversion strategy.

def create_long_short_market_signals(pairs, symbols, z_entry_threshold=2.0, z_exit_threshold=1.0):  

I assume the above function creates the entry and exit criteria of Z-score. The criteria is to enter at 2.0 Standard Deviation and exit when Z-score falls to 1.0 Standard Deviation.

    pairs['longs'] = (pairs['zscore'] <= -z_entry_threshold)*1.0  
    pairs['shorts'] = (pairs['zscore'] >= z_entry_threshold)*1.0  
    pairs['exits'] = (np.abs(pairs['zscore']) <= z_exit_threshold)*1.0  

The above codes within the def function() is to go Long when Zscore is -2.0SD and Short when Zscore is +2.0SD. The signal will exit when Zscore falls to <= +1.0SD.

I think the above codes, I can understand the logic for the program to create a Short and Long command if Zscore is above 2.0 Standard Deviation or below -2.0 Standard Deviation.

But regarding the Exit command I need some clarification about my understanding of it.

Q1) The program is written by telling the signal to exit the trade only when Zscore is <= 1.0. So assuming between -2.0SD to 1.0SD, the program continues to stay Long and it do nothing even if the signal crosses a Zscore of -1.0?

Q2) Also, if we want to create both an Exit signal of 1.0 Standard Dev and -1.0 Standard Dev, we should write the functions code as per below am I correct? :

def create_long_short_market_signals(pairs, symbols, z_entry_threshold_1=2.0, z_entry_threshold_2= -2.0, z_exit_threshold_1=1.0, z_exit_threshold_2= -1.0):  

If anyone is interested to see the full function, it is below. The codes are written with no specific backtesting libraries. Its just python and pandas.

# mr_spy_iwm.py  
def create_long_short_market_signals(pairs, symbols,  
                                 z_entry_threshold=2.0,  
                                 z_exit_threshold=1.0):  
    """Create the entry/exit signals based on the exceeding of  
    z_enter_threshold for entering a position and falling below  
    z_exit_threshold for exiting a position."""

    # Calculate when to be long, short and when to exit  
    pairs['longs'] = (pairs['zscore'] <= -z_entry_threshold)*1.0  
    pairs['shorts'] = (pairs['zscore'] >= z_entry_threshold)*1.0  
    pairs['exits'] = (np.abs(pairs['zscore']) <= z_exit_threshold)*1.0

    # These signals are needed because we need to propagate a  
    # position forward, i.e. we need to stay long if the zscore  
    # threshold is less than z_entry_threshold by still greater  
    # than z_exit_threshold, and vice versa for shorts.  
    pairs['long_market'] = 0.0  
    pairs['short_market'] = 0.0

    # These variables track whether to be long or short while  
    # iterating through the bars  
    long_market = 0  
    short_market = 0

    # Calculates when to actually be "in" the market, i.e. to have a  
    # long or short position, as well as when not to be.  
    # Since this is using iterrows to loop over a dataframe, it will  
    # be significantly less efficient than a vectorised operation,  
    # i.e. slow!  
    print "Calculating when to be in the market (long and short)..."  
    for i, b in enumerate(pairs.iterrows()):  
        # Calculate longs  
        if b[1]['longs'] == 1.0:  
            long_market = 1  
        # Calculate shorts  
        if b[1]['shorts'] == 1.0:  
            short_market = 1  
        # Calculate exists  
        if b[1]['exits'] == 1.0:  
            long_market = 0  
            short_market = 0  
        # This directly assigns a 1 or 0 to the long_market/short_market  
        # columns, such that the strategy knows when to actually stay in!  
        pairs.ix[i]['long_market'] = long_market  
        pairs.ix[i]['short_market'] = short_market  
    return pairs  

I hope my question is asked in a clear manner and people can understand what I'm trying to ask. Thanks a lot in advance :)

2 responses

Hey Jasen,

From what I can see it looks like your logic seems solid. But you'd have to implement this

"def create_long_short_market_signals(pairs, symbols, z_entry_threshold_1=2.0, z_entry_threshold_2= -2.0, z_exit_threshold_1=1.0, z_exit_threshold_2= -1.0): "

logic somewhere in the "for i,b" section of the code

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.

Hi Seong Lee,

Thanks for the guidance. Actually I posted just part of the program codes. The whole program is really not robust at all with a few technicalities yet to sort out. I also saw your work on the other mean regression you did. Neat work and I think its definitely more robust than what I've got.

Will look into it. Wish you a happy 2015.