Contrarian trading is based on the fact that the market has reached an extreme and is bound to reverse its course. Many momentum indicators have been proposed to predict when will the reversal happen. Some are known such as the Relative Strength Index and some are less popular such as the Moving Average Contrarian Indicator but they mostly take into account only basic variables such as the closing price or its moving average.
In this article, we will look at an enhanced Momentum concept that includes correlation in its system to signal market extremes. But first, we will quickly go through some introductory concepts related to Momentum and Correlation.
If you are interested in seeing more indicators, feel free to check out the below article:
The Momentum Indicator
Momentum is an interesting concept in financial time series. Most strategies are either trend-following or mean-reverting. Momentum is the strength of the acceleration to the upside or to the downside, and if we can measure precisely when momentum has gone too far, we can anticipate reactions and profit from these short-term reversal points. One way to measure momentum is by the Momentum Indicator.
The Momentum Indicator’s formula is extremely simple and can be summed up in the below mathematical representation:
What the above says is that we can divide the latest (or current) closing price by the closing price of a previous selected period, then we multiply by 100. Hence, if we say we are going to use Momentum(14), then, we will subtract the current values from the values 14 periods ago and then divide by 100.
The Momentum Indicator is not bounded as can be seen from the formula, which is why we need to form a strategy that can give us signals from its movements.
The above graph shows the EURUSD values versus the Momentum Indicator of 3 periods. This means we are simply dividing the current closing price by the price 3 periods ago and multiplying by 100. Below is the Python code to create a function that calculates the Momentum Indicator on an OHLC array.
def momentum_indicator(Data, what, where, lookback):
for i in range(len(Data)):
Data[i, where] = Data[i, what] / Data[i - lookback, what] * 100
return Data# The Data variable is the OHLC array
# The what variable is the closing price column
# The where variable is where to put the indicator
# The lookback variable is the subtraction range
The Concept of Correlation
Correlation is the degree of linear relationship between two or more variables. It is bounded between -1 and 1 with one being a perfectly positive correlation, -1 being a perfectly negative correlation, and 0 as an indication of no linear relationship between the variables (they relatively go in random directions). The measure is not perfect and can be biased by outliers and non-linear relationships, it does however provide quick glances to statistical properties.
We will use the concept of Autocorrelation which is the correlation of the variable with lagged values of itself. This means that the market price will be compared to previous market prices to see whether it is correlated in time or not. The function I use to do this is as follows:
def auto_correlation(Data, first_data, second_data, shift_degree, lookback, where):
new_array = shift(Data[:, first_data], shift_degree, cval = 0)
new_array = np.reshape(new_array, (-1, 1))
Data = np.concatenate((Data, new_array), axis = 1)
Data = adder(Data, 20)
for i in range(len(Data)):
Data[i, where] = pearsonr(Data[i - lookback + 1:i + 1, first_data], Data[i - lookback + 1:i + 1, second_data])
We can see that autocorrelation of prices fluctuates in cycles as it breaks from time to time. It is reasonable to assume that momentum breaks whenever we have historically high correlations. This will be the idea of the K’s Momentum Indicator that we will discuss in the next part.
The K’s Momentum Indicator — KMI
The idea of the K’s Momentum Indicator is to provide contrarian trading signals based on two simple conditions:
- For a long (Buy) signal: The current value of the Momentum Indicator is less than the value five periods ago while simultaneously, the autocorrelation is very high and equal to or above 0.85.
- For a short (Sell) signal: The current value of the Momentum Indicator is greater than the value five periods ago while simultaneously, the autocorrelation is very high and equal to or above 0.85.
The intuition of this is that when the Momentum goes on for five periods and the market price is highly correlated to its previous values, then a structural break might occur. You can use any lookback period you want, it does not have to be five.
The reason I call it the K’s Momentum Indicator is because of my last name.
Back-testing the Strategy
Now, it is time to back-test this indicator using the above conditions which can be again mentioned:
- Go long (Buy) whenever the current value of the Momentum Indicator is less than the value five periods ago while simultaneously, the autocorrelation is very high and equal to or above 0.85.
- Go short (Sell) whenever the current value of the Momentum Indicator is greater than the value five periods ago while simultaneously, the autocorrelation is very high and equal to or above 0.85.
- The risk management is based on the Average True Range detailed in the next part.
def signal(Data, auto_corr, moment, buy, sell):
for i in range(len(Data)):
if Data[i, auto_corr] > upper_barrier and Data[i, moment] < Data[i - lookback, moment]:
Data[i, buy] = 1if Data[i, auto_corr] > upper_barrier and Data[i, moment] > Data[i - lookback, moment]:
Data[i, sell] = -1
The above code snipper is the signal function that simply states if the autocorrelation is high enough and the Momentum Indicator is showing an extreme value, then we should initiate the appropriate trade.
The strategy seems to perform well on the AUDCAD through a more or less stable upward sloping equity curve.
The same thing goes for the USDCHF and EURCHF pair. Overall, the strategy performs well on these selected pairs with others also showing above average return.
A Word on Risk Management
When I say I use ATR-based risk management system (Average True Range), it means that the algorithm will do the following steps with regards to the position it takes.
A long (Buy) position:
- The algorithm initiates a buy order after a signal has been generated following a certain strategy.
- Then, the algorithm will monitor the ticks and whenever the high equals a certain constant multiplied by ATR value at the time of the trade inception, an exit (at profit) order is initiated. Simultaneously, if a low equals a certain constant multiplied by ATR value at the time of the trade inception is seen, an exit (at loss) is initiated. The exit encountered first is naturally the taken event.
A short (Sell) position:
- The algorithm initiates a short sell order after a signal has been generated following a certain strategy.
- Then, the algorithm will monitor the ticks and whenever the low equals a certain constant multiplied by ATR value at the time of the trade inception, an exit (at profit) order is initiated. Simultaneously, if a high equals a certain constant multiplied by ATR value at the time of the trade inception is seen, an exit (at loss) is initiated. The exit encountered first is naturally the taken event.
The plot above shows the Average True Range I generally use. It is based on an exponential moving average as opposed to the original smoothed moving average.
Take a look at the latest value on the ATR. It is around 0.0014 (14 pips). If we initiate a buy order following a simple 2.00 risk-reward ratio (risking half of what we expect to gain), we can place an order this way:
- Buy at current market price.
- Take profit at current market price + (2 x 14 pips).
- Stop the position at current market price — (1 x 14 pips).
As always, we back-test and analyze the results. But when do we know that we have a winning strategy? That can be answered by applying the following steps into any back-tested strategy:
- The transaction costs should be represented as accurately as possible. The majority of strategies are sensitive to transaction costs. In the above back-tests, I have used very low costs of 0.2 pip per round trade.
- The back-tests should relatively perform well across the time frames due to the self similarity property of the financial markets. This also ensures that you back-test it using different costs.
- The strategies should not be overly sensitive to changes in its variables. For example, if you use a lookback period of 4 on an indicator, then using a lookback period of 5 should not change drastically the results.
Why was this article written? It is certainly not a spoon-feeding method or the way to a profitable strategy. If you follow my articles, you will notice that I place more emphasize on how to do it instead of here it is and that I also provide functions not full replicable code. In the financial industry, you should combine the pieces yourself from other exogenous information and data, only then, will you master the art of research and trading.
I always advise you to do the proper back-tests and understand any risks relating to trading. For example, the above results are not indicative as the spread we have used is very competitive and may be considered hard to constantly obtain in the retail trading world (but not impossible). However, with institutional bid/ask spreads, it may be possible to lower the costs such as that a systematic medium-frequency strategy starts being very profitable. You must never expect guaranteed returns and it is your sole responsibility to generate your own signals.