Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
how to take trades according to the rolling zscore of a pairs trade?

Hello,
I am new around here and therefore decided to take a look at this lecture https://www.quantopian.com/lectures/introduction-to-pairs-trading more specifically the 30 day rolling zscore. However he never explains how to interpret the zscore in a trading manner, he says if the zscore is above the threshold(1) then you should short the spread, but what does that even mean in an actual shares trading context?

Say you have the following spread between stock MRK.DE and AOX.DE, how would one actually trade it? Since we are below the threshold we should be long the spread however what does this entail? Long MRK, short AOX or long both or something completely different?
Spread illustrated: https://ibb.co/djRWvHT

19 responses

There are two algorithms in Lecture 45 and Lecture 46 which give examples of code to actually trade.

In pairs trading one always holds a long position in one stock and a short position in the other. One is trying to 'hedge' the effects of the market's unavoidable ups and downs. So, if the market goes down, the assumption is both stocks would also go down. By holding both a long and a short position the net impact from this market change would hopefully be zero.

Which stock to long and which to short, at any given time, is determined by the sign of z-score of the current the spread. Assume there are two stocks X and Y. Also assume the spread is defined as the price of Y minus the price of X . If the z-score is positive, then it implies the spread is above the mean spread. This could be because the price of X is very low or Y is very high (or maybe both). The assumption is the spread will revert to the mean so X should go up or Y should go down (or maybe both). So, with the above definition of the spread, if the z-score is positive, go long X and go short Y. If the z-score is negative, short X and long Y.

The z-score sign indicates the 'direction' of each position, but how large a relative position of each to take? Should we take an equal position of each? We are expecting the market shorted stock to change an equal (and opposite) amount as the long stock. But, historically our two stocks X and Y may not change equally. If X goes up 1%, Y may only go up .5%. This expected price change, relative to X, is a stocks 'beta' relative to X. A beta of 1 means it typically moves the same as X. Therefore, if we want to hedge a long and a short position, and expect them to equal out any price movements, the ratio of X to Y should be the beta of Y. Take a simple example. Assume Y has a beta of .5 relative to X. If X goes down 1% we would expect Y to go down .5 x 1% or .5%. If we were holding X long and Y short with equal positions, X would go down 1% and Y up .5% for a net loss of .5%. We want our net loss to be zero. Therefore, we need to have our position of X to be half the position of Y. The ratio of the position X/Y should the beta of Y relative to X (ie beta_Y times position_value_X = position_value_Y)

The calculation of beta, as well as the ratio of the positions and determining the direction based upon z-score, are coded in the two algos referenced above.

Hope that helps.

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.

@Dan Whitnable
Take a look at this. At approximately 10:45 am (GMT+1, Copenhagen) I calculated the Z-score for each of the below pairs:

Possible trade at MRK.DE AOX.DE. Stddev: 0.28. Current spread: [-2.21866881].
Possible trade at NEM.DE SHA.DE. Stddev: 0.33. Current spread: [-2.23626499].
Possible trade at HNR1.DE FPE.DE. Stddev: 0.38. Current spread: [2.27174249].
Possible trade at MRK.DE NOEJ.DE. Stddev: 1.12. Current spread: [-1.98877657].
Possible trade at MRK.DE AIR.DE. Stddev: 2.67. Current spread: [-2.14303357].
Possible trade at SAP.DE KGX.DE. Stddev: 2.85. Current spread: [-2.49708246].

Now when I calculate the Z-score for the same stocks (Im using the moving average method described in the lecture) I get this at the end of the trading day today (note I have written the price change in % for from 10:45 am to market close next to each of the stocks in parentheses):

ATTENTION: Open trade at MRK.DE (-2,78%) AOX.DE (-1,77%). Stddev: 0.28. Current spread: [-1.25071216].
ATTENTION: Open trade at NEM.DE (-2,3%) SHA.DE (0,63%). Stddev: 0.33. Current spread: [-1.41698111].
ATTENTION: Open trade at HNR1.DE (-2,11%) FPE.DE (0,18%). Stddev: 0.38. Current spread: [2.08791043].
ATTENTION: Open trade at MRK.DE (-2,78%) AIR.DE (-5,01%). Stddev: 2.65. Current spread: [-1.49187867].
ATTENTION: Open trade at SAP.DE (-4,07%) KGX.DE (-4,03%). Stddev: 2.83. Current spread: [-1.62708333].

As you can see from the above now open trades at the end of the day and their respective price move from 10:45 am to 5:30 pm many of them move the same direction (negative) yet the score moves towards 0 on all of these trades (they are all lower than before). So my question stands, if my threshold is 1,96 and -1,96 for taking trades, which stock should I buy and which should I short, because looking at the above results its very unclear what makes the score move.

The determination of which to long and which to short is based upon the sign of the z-score and the definition one uses for the spread. I'm not sure how you defined the spread but let's assume it is

spread = Y - X
If the z-score is positive, go long X and go short Y.
If the z-score is negative, go long Y and go short X.

So, using some real tickers from above

X = MRK.DE
Y = AOX.DE
spread = price of MRK.DE - price of AOX.DE = -2.21866881
the current spread is negative so go long Y (AOX.DE) and go short X (MRK.DE)

This of course would be reversed if your definition of X and Y were reversed.

Let's look at what would have happened if you entered an equal position of long AOX.DE and short MRK.DE at 10:45:

MRK.DE price down 2.78%, Since this is shorted it will be a gain of 2.78%
AOX.DE price down 1.77%. Since this is long it will be a loss of 1.77%
NET GAIN = 2.78 - 1.77 = 1.01%

So yes, both lost but since one is holding both a long and short position the net is positive. Actually, the stats above demonstrate pairs trading surprisingly well. As stated, all the spreads move closer to zero. This is the fundamental hypothesis of pairs trading - that the spread reverts to the mean so therefore the z-scores moves closer to zero. In all five cases above, the spreads moved closer to zero by the end of the day. This of course doesn't always happen but interesting to see in this case.

Second, assume the spread definition is Y - X where X is the first stock of each pair and Y is the second in the list above. If the spread is negative then short X and long Y (ie short MRK, NEM, HNR1, MRK, SAP and long AOX, SHA, AIR, KGX). Looking at the price changes listed above from 10:45 to the end of day, and assuming an equal position size for each, one would have made money on all but one of those pairs trades (ie 2.78-1.77, 2.3+.63, 2.78-5.01, 4.07-4.03). Now consider the pair where the spread was positive (HNR1.DE FPE.DE). One would have gone long HNR1 and short FPE. Looking at the end of day gains (-2.11% and .18% respectively) the net loss would have been -2.11-.18.

Again, these long short positions would all be reversed if the spread calculation is reversed to be X - Y. I didn't know how it was actually calculated. Also, one would need to calculate the actual position sizes using the beta of Y relative to X which may change the net gain results.

Note that pairs trading isn't a crystal ball. It doesn't always result in winning trades (as seen above) but the premise is that, over the long term, the net results will be positive.

Hope this helps.

Hello Dan, Im litterally copy pasting the spread calculation etc. from the lecture here: https://www.quantopian.com/lectures/introduction-to-pairs-trading

That means that the spread is calculated the following way:

         Xl = np.array([StockAData, StockBData]).T

        lineStd = coint.fit_transform(Xl).std()  
        spread = coint.fit_transform(Xl)

        S1 = sm.add_constant(StockAData)  
        results = sm.OLS(StockBData, S1).fit()  
        S1 = S1[StockAApart]

        rolling_beta = ols.PandasRollingOLS(y=S1, x=StockBData, window=30)  
        spread = StockBData - rolling_beta.beta["feature1"] * S1  
        spread.name = 'spread'

            # Get the 1 day moving average of the price spread  
        spread_mavg1 = spread.rolling(1).mean()  
        spread_mavg1.name = 'spread sma(1) mavg'

            # Get the 30 day moving average  
        spread_mavg30 = spread.rolling(30).mean()  
        spread_mavg30.name = 'spread sma(30) mavg'

        std_30 = spread.rolling(30).std()  
        std_30.name = 'std 30'

        series_spread = (spread_mavg1 - spread_mavg30)/std_30  

So I am again asking how to interpret the score regarding to what you should long or short, because if look at the the last spread (SAP and KGX) they both fell around the same but the zscore spread changed by 0,9!

It is a bit unfortunate that the code uses 'S1 and S2' and 'A and B' and then later in the algo 'X and Y' to indicate which stock is which. However, they all refer to the 'first on and the second on' so we just need to keep the order straight. I'll make the assumption that the order for SAP and KGX is this

S1 = prices_df['SAP']  
S2 = prices_df['KGX']

I'll assume the calculations were done correctly so, since the z-score of the spread was negative, one should long KGX and short SAP. If one swapped the definitions of S1 and S2 then one would swap which to long and short (but presumably the sign of the of z-score spread would swap too so it would result in the same trades).

The reason why the spread decreased even though both prices dropped about the same is because of the definition of 'spread' being used.

spread = StockBData - rolling_beta.beta["feature1"] * S1 

Notice that S1 is 'weighted' by beta. If that beta is 1 then a similar price change in both S1 and S2 would result in no change to the spread. However, if beta is greater than 1 then the spread would decrease even though both prices fell by the same.

I left the hedge multiplier out of the spread examples above and assumed it to be 1 just for simplicity. But, more generally, it should be

spread = Y - hedge * X  
# where hedge is the beta found by the ordinary least squares (OLS) relationship  
# Y = beta * X  + alpha

Including the hedge multiplier impacts how the spread changes relative to changes in X and Y.

Does that make sense?

I see, thanks for the clearification, I have but one question remaining now.

If the spread depends on the beta then how can it be considered a solid buy/sell signal? Yes the spread is meanreverting but even thought the selected stocks are cointegrated as a cointegration test shows, this doesn't equal that a meanreversion in the spread is equal to a profit in the long/short stocks of the spread. So would the "correct" way to calculate the spread be by setting the hedge (beta) to just 1 or keeping it as is?

@Toma Christensen , Actually , what you should understand is that "beta" is a coefficient that gives the relationship between the evolution of X and Y. It seems that you're always taking the case where "beta = 1" but It's not always the case.Actually , I would like to say rarely the case to not say never.This is the first thing. Second , We have no guarantee that "beta" will remains constant over time and I guess It has also effect in the cointegration of the pairs thus in the stationarity of the spread.This is why in the lecture , they said that it's not because the time series is stationary that it will remains stationary and they suggest us to make some tests of stationarity consistency....
Anyway , "beta" is basically what rely X and Y and we use it as way to hedge our positions.This is why Pairs Trading is Market Neutral.

I'm not sure that I have 100% answered to your question because It wasn't clear for me but I tried to answer what I've understood

Actually , in the signal buy/sell there is no problem even if you have a problem with "beta".

let's assume that : spread = X - Y

if spread positive : we short X and long Y
if spread negative : we short Y and long X

Until here no problem with beta.

Now, I have 2 questions for you :

--> Can X and Y evolving in the same direction ? OF COURSE , YES !!

-->Does X evolving with the same "velocity" as Y in the same direction ? OF COURSE , NOT !!

==> The beta is a way to quantify the ratio of their velocities and this is very useful to hedge our position otherwise the Market Neutrality will not be guarantee !!

@BIBANI Iheb
I guess what I am trying to get an answer on is 2 things:
1. What should the formula for the spread be? Spread=X-Y or Spread=StockBData - rolling_beta.beta["feature1"] * S1
2. Depending on the spread what would be the "correct" way to trade it to achieve the desired market neutrality effect and hopefully some profit.

The reason for me making this entire post was just because of the confusion of how both assets can move in the same direction and the spread still moves towards 0, although this has now been answered it does leave a bit of a worry about wether or not the spread is actually tradeable (question 1).

Beta (or something similar) needs to be accounted for somewhere. Somewhere in the calculations one needs to at least address the fact that stocks aren't priced similarly. What if stock X is selling for $10 and stock Y $100? Assume they both go up and down identically perhaps 10% (to make the math easy). One should expect the spread to go up and down identically too. Let's see how that would work without beta

spread_initial = 100 - 10 = 90  
spread_after_10_pct_gain = 110 - 11 = 99

Hmm. Not what we expected. If the stocks do go up and down identically then the beta of Y relative to X would be Y = beta * X which implies beta = 10 (ie 100 = 10 * 10). Let's see what this added beta factor does.

spread_initial = 100 - (beta * 10) = 100 - 100 = 0  
spread_after_10_pct_gain = 110 - (beta * 11) = 110 - 110 = 0

Ah, that's better. The spread now remains constant. One at least needs a factor to normalize the two prices so they can be compared.

Adding a beta additionally accounts for the reality that not all stocks move up and down with the market the same (their betas relative to the market are different). Remember we are trying to hedge against market swings. Let's take another example. This time the stocks X and Y are priced the same at $100. The difference is they do not move uniformly with the market. Stock X generally moves the same as the market. Its beta relative to the market is 1. However, stock Y is more volatile. It sees bigger swings and has a beta, relative to the market, of 1.1. Let's see what a 10% gain in the market does if we don't include beta in our spread calculation.

spread_initial = 100 - 100 = 0  
spread_after_10_pct_mkt_gain = (100 *1.1*1.1)  - (100 * 1.1)  = 121 - 111 = 10

Again, that doesn't look right. Let's add our beta to the hedge calculation. Now assume the beta of Y relative to X is just our beta relative to the market or 1.1. Let's now see what our spread is.

spread_initial = 100 - 100 = 0  
spread_after_10_pct_mkt_gain = (100 *1.1*1.1)  - (beta *(100 * 1.1) ) = 121 - (1.1 * 110) = 0

Much better. Including beta into our hedge calculation not only does the price 'scaling' for us, but it also accounts for stocks which don't move equally with the market (ie their beta to the market values differ).

This was a long winded way of saying, yes one needs to include the beta of Y with respect to X in the hedge calculation. I should have really included that in my original example.

@Dan I would say that even though that explanation was long it was well worth it! Thank you so much, this makes it far easier to understand. However you don't happen to remember a formula from the top of your head to calculate the optimal % allocation in stock a and stock b based on the beta? I don't want to be a nuisance but might aswell ask while I'm at it.

@Tomas

1- the correct way is this one : Spread=StockBData - rolling_beta.beta["feature1"] * S1

2- what would be the "correct" way to trade ? Use OLS(Y,X).fit to find "beta"

@Dan
I've now taken into account the hedge ratio, comparing yesterdays trades again it should now have looked like this instead:

ATTENTION: Open trade at MRK.DE AOX.DE. Stddev: 0.27. Current spread: [-2.46788803]. Sell 3.3x AOX.DE for every MRK.DE
ATTENTION: Open trade at NEM.DE SHA.DE. Stddev: 0.32. Current spread: [-2.47328773]. Sell 2.96x SHA.DE for every NEM.DE
ATTENTION: Open trade at HNR1.DE FPE.DE. Stddev: 0.39. Current spread: [2.41875875]. Buy 6.11x FPE.DE for every -HNR1.DE
ATTENTION: Open trade at MRK.DE AIR.DE. Stddev: 2.61. Current spread: [-2.24220584]. Sell -0.41x AIR.DE for every MRK.DE
ATTENTION: Open trade at SAP.DE KGX.DE. Stddev: 2.79. Current spread: [-2.58256542]. Sell -0.54x KGX.DE for every SAP.DE

Which when calculating the adjusted profits at the end of the day would result in:

Status MRK AOX NEM SHA HNR1 FPE MRK AIR SAP KGX
Buy (% profit) -2,78 -2,3 1,10 -2,78 -4,07
Sell (% profit) 5,84 -1,86 2,11 2,05 2,18
Total Profit 3,06 -4,16 3,21 -0,73 -1,89

This does look a tad bit better than what would otherwise have occurred have one traded in fixed sizes. I'd like to thank you for the clarification. Please do tell if this is incorrect though

Hello @Dan ,

Thanks for your explanation , it is more clear for me.

However , I don't understand here :

"Beta (or something similar) needs to be accounted for somewhere. Somewhere in the calculations one needs to at least address the fact that stocks aren't priced similarly. What if stock X is selling for $10 and stock Y $100? Assume they both go up and down identically perhaps 10% (to make the math easy). One should expect the spread to go up and down identically too. Let's see how that would work without beta"

what do you mean ? That stocks goes both up , then down and the overall percentage_change is 10% ? (I don't think ...because otherwise you'll say directly that the percentage_change evolved by +10% and in enough but you said both up , both down so there is a reason , can you explain me ?)

The other question we have two betas ?
- One to rely sensitivity between stocks and market
- Another one to rely stocks with the hedge ratio
However , rolling beta is , I guess , a hedge ratio why in the lecture they didn't put it ? Or more interesting question , how to calculate it ..

Thanks

@BIBANI Iheb is correct. I haven't explicitly stated how to find the beta of Y relative to X but use statsmodels OLS or some similar method. In calculating the z-scores one needs a series of past spreads to calculate the mean. The beta will vary with time, so one approach is to use a 'rolling' calculation of beta to weight the X prices.

There was a question about how much to allocate to each stock X and Y? One will find several approaches to this if doing an internet search. Often the approach is to have equal size positions so the strategy is 'market neutral'. I don't exactly agree with that (for reasons demonstrated in the example below) but I do want to say there isn't a universal approach. That said, I would allocate with a ratio of -beta of Y relative to X. If one orders $1000 of Y then order -beta x $1000 of stock X. Of course one position will be long and the other short depending upon the sign of the spread.

An example of how this works. We are trying to protect from market movements so the size of the long and short positions should 'balance' each other. Again assume we have stocks X and Y which are priced the same at $100. The difference is they do not move uniformly with the market. Assume stock X generally moves the same as the market. Its beta relative to the market is 1. However, stock Y is more volatile. It sees bigger swings and has a beta, relative to the market, of 1.1. Since X moves the same as the market, the beta of Y relative to X can be taken as the beta to the market. Let's see what happens to a portfolio with a 10% gain in the market. Assume X and Y just move with the market and there is no underlying price reversion.

# note we assume we are shorting X  
net_initial_position = pos_Y + pos_X  
net_initial_position = $1000 + (-beta * $1000) = $1000 + (-1.1 * $1000) = $1000 - $1100 = -$100

net_final_position_10_pct_mkt_gain = (pos_Y  * y_gain) + (pos_X * x_gain)  
net_final_position_10_pct_mkt_gain = ($1000 * (1+(.1*1.1))) + (-$1100 * (1+.1)  = $1110 - $1210 = -$100

Great. With a big market swing our market neutral strategy left our portfolio untouched with the same initial value of -$100. Now let's see what a 10% market loss does.

# again note we assume we are shorting X  
net_initial_position = pos_Y + pos_X  
net_initial_position = $1000 + (-beta * $1000) = $1000 + (-1.1 * $1000) = $1000 - $1100 = -$100

net_final_position_10_pct_mkt_loss = (pos_Y  * y_gain) + (pos_X * x_gain)  
net_final_position_10_pct_mkt_loss = ($1000 * (1-(.1*1.1))) + (-$1100 * (1-(.1))) = ($1000*.89) - ($1100 *.9) = $890 - $990 = -$100

While we probably weren't ecstatic that our market neutral strategy remained flat when the market went up 10%, we should be happy that when the market went down 10% we didn't loose anything.

So, the dollar amount to portion to each position, to remain market neutral, is

X_position = -beta * Y_position. 

One way to think of this is, if the beta of Y relative to X is greater than 1, then Y is more volatile than X. Y will have larger price swings. Therefore, to compensate for the larger Y swings, one needs to hold a proportionately larger position of X.

Conversely, if beta is less than 1, then Y is less volatile than X. Y will have smaller price swings. To match the smaller Y swings, one needs to hold a proportionately smaller position of X.

This weighting can be seen implemented in the Lecture 46 pairs trading algo.

@Dan
I really have my doubts that the following rule applies. I will explain why:

If spread is above threshold we sell stock A and buy stock B.  
If spread is below threshold we buy stock A and sell stock B.  

The reason i am doubting the above is because of the case that is the spread between MRK and NOEJ. I am using the following calculation for hedge and the previously mentioned calculation of the spread with beta.

def hedge_ratio(Y, X, add_const=True):  
    if add_const:  
        X = sm.add_constant(X)  
        model = sm.OLS(Y, X).fit()  
        return round(model.params[1], 2)  
    model = sm.OLS(Y, X).fit()  
    return round(model.params.values, 2)  

Now going back to 3 days ago on 2020-09-03 at 10 am (GMT+2), we get the following trade signal:
ATTENTION: Open trade at MRK.DE NOEJ.DE. Stddev: 1.14. Current spread: [-2.11988616]. Sell -0.91x NOEJ.DE for every buy of MRK.DE

As the spread is below the threshold (-1.96) we buy stock A (MRK) and short stock B (NOEJ). However just 8 trading hours later at 9 am 2020-09-04 (GMT+2) the spread has changed to:
ATTENTION: Open trade at MRK.DE NOEJ.DE. Stddev: 1.13. Current spread: [0.08439562] This gives us a signal to close the trade since it has crossed the zero line. But why is this the case? The trade will have lost money even with the correct hedge (which is 0.91x NOEJ).
In the period the trade is open the long trade in MRK ends in -2.3% and our short in NOEJ ends in -1.82%, since we were short and it rose (2%*hedge=1.82%).
So in total the spread trade loses us -2.3%+-1.82%=-4.12%. Yet the zscore spread doesn't show this as it just goes towards 0 instead of widening. How can this be, are you sure that its not the otherway around (Short stock A and buy stock B if below threshold)?

@DAN ,

I've found many pairs between sectors in my country and I would like to use PAIRS TRADING. However, we are not allowed to SHORT.

Can I long what should have been long , than following the pairs until convergence to 0 then I decide to exit my position ?

I know that I'll not be covered but can I anyway follow the signal (I guess yes....)

Another question , how can we "optimize" our thresholds choices ?

Thanks for your answer

@DAN ,

I have another question : As a signal , the "right" time to sell/buy in my case is it the same between the spread and in the case where I've adopted a mean reversion strategy. I know that PAIRS TRADING is based on that....but my question is stated about the signal to take positions , are they the same between PAIRS TRADING AND MEAN REVERSION ?

Thanks a lot

To add onto the results of the strategy here are some of the results from yesterday to today.

Entering the below trades at 11:30 GMT+2 2020-09-07

Possible trade at NEM.DE IFX.DE. Stddev: 0.44. Current spread: [-2.34131085]. Sell -2.34x IFX.DE for every NEM.DE  
Possible trade at HEN3.DE SZG.DE. Stddev: 0.46. Current spread: [2.49297692]. Buy 1.39x SZG.DE for every -HEN3.DE  
Possible trade at FPE.DE OSR.DE. Stddev: 0.52. Current spread: [2.00577857]. Buy -0.78x OSR.DE for every -FPE.DE  
Possible trade at PUM.DE NOEJ.DE. Stddev: 1.09. Current spread: [2.05171766]. Buy 0.85x NOEJ.DE for every -PUM.DE  
Possible trade at BAS.DE VOW3.DE. Stddev: 1.86. Current spread: [2.13772562]. Buy 0.33x VOW3.DE for every -BAS.DE  
Possible trade at RHM.DE AIR.DE. Stddev: 3.03. Current spread: [1.99226657. Buy -0.33x AIR.DE for every -RHM.DE  
Possible trade at NEM.DE MUV2.DE. Stddev: 3.86. Current spread: [-2.26960135]. Sell -0.27x MUV2.DE for every NEM.DE  
Possible trade at MUV2.DE SRT.DE. Stddev: 7.79. Current spread: [-2.11892304]. Sell -0.38x SRT.DE for every MUV2.DE  
Possible trade at NEM.DE SRT.DE. Stddev: 8.35. Current spread: [-2.19639924]. Sell -0.13x SRT.DE for every NEM.DE  
Possible trade at SAP.DE SRT.DE. Stddev: 9.76. Current spread: [-2.01099398]. Sell -0.12x SRT.DE for every SAP.DE  

Looking today (2020-09-08 12 am GMT+2) we get the following spreads for the previously taken trades:

ATTENTION: Open trade at NEM.DE IFX.DE. Stddev: 0.46. Current spread: [-1.28238652]. Buy 2.27x IFX.DE for every -NEM.DE  
ATTENTION: Open trade at HEN3.DE SZG.DE. Stddev: 0.46. Current spread: [0.784125]. Buy 1.31x SZG.DE for every -HEN3.DE  
ATTENTION: Open trade at FPE.DE OSR.DE. Stddev: 0.51. Current spread: [-0.90834821]. Buy -0.78x OSR.DE for every -FPE.DE  
ATTENTION: Open trade at PUM.DE NOEJ.DE. Stddev: 1.08. Current spread: [1.68687877]. Buy 0.86x NOEJ.DE for every -PUM.DE  
ATTENTION: Open trade at BAS.DE VOW3.DE. Stddev: 1.91. Current spread: [1.33216638]. Buy 0.32x VOW3.DE for every -BAS.DE  
ATTENTION: Open trade at RHM.DE AIR.DE. Stddev: 2.95. Current spread: [1.05365243]. Buy -0.35x AIR.DE for every -RHM.DE  
ATTENTION: Open trade at NEM.DE MUV2.DE. Stddev: 3.92. Current spread: [-1.05973375]. Buy 0.27x MUV2.DE for every -NEM.DE  
ATTENTION: Open trade at MUV2.DE SRT.DE. Stddev: 7.67. Current spread: [-1.06324422]. Buy 0.39x SRT.DE for every -MUV2.DE  
ATTENTION: Open trade at NEM.DE SRT.DE. Stddev: 7.86. Current spread: [-1.07167311]. Buy 0.14x SRT.DE for every -NEM.DE  
ATTENTION: Open trade at SAP.DE SRT.DE. Stddev: 9.8. Current spread: [-0.90789959]. Buy 0.11x SRT.DE for every -SAP.DE

Giving a total profit for each of these trades adjusted with their respective hedge:
-2,95% for all pairs. Further details in this screenshot: https://ibb.co/jLkgPvv

Also how come some of the hedges are negative? What does that even mean? For any pair and direction of the pairs the hedges will sometimes be negative, how can you buy -3,92x for every short of the other stock?
Again, as I haven't gotten any confirmation on my original question, what is the correct long/short combination of the pairs when hedges are taken into account?