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 :)