"Technical" indicators are useful for measuring short-term momentum of stock prices. Although technically we can measure momentum of other metrics like Price-Over-Eraning (P/E) or EV/EBITDA, price of a stock is an important metric to apply momentum over.

There are various indicators already -

- Relative Strength Index (RSI)

```
RSI = 100 – [100 / ( 1 + (Average of Upward Price Change / Average of Downward Price Change ) ) ]
```

- Moving Averages: SMA50, SMA200, EMA (Exponential Moving Average: gives more weight to recent prices compared to old prices)

But instead of these short-term momentum indicators (used primarily by "traders" as opposed to long-term investors), was keen on designing some indicator for long-term trends which takes both - volatility and momentum into account. Also the designed metric should work well for both - Bull market and Bear market, given the fact that it's easier to design such a momentum indicator for a rising Bull market.

To facilitate the discussion we are going to refer three BSE-listed Indian companies -

- Triveni Turbine Ltd (Heavy Electrical Equipment)

- Vardhman Holdings Ltd Finance (including NBFCs)

Leaving out Infosys, even though both companies would have given fantastic returns, the volatility of Vardhman Holdings Ltd is lesser. Standard measure of volatility - standard deviation - is too granular and downright wrong, IMO.

```
> sd(t.Vardhman)
[1] 662.1091
> sd(t.Triveni)
[1] 11.22787
```

FYI, I'm using Quandl API to fetch the pricing data -

```
Quandl_Fetch <- function(ticker, look_back_window = years(1)) {
stock <- Quandl(ticker,
start_date=as.character(ymd(Sys.Date()) - look_back_window),
end_date=as.character(ymd(Sys.Date())))
# Create the time series
t <- xts(stock$Close, stock$Date)
t
}
```

```
> t.Triveni <- Quandl_Fetch(ticker = "BSE/BOM533655", look_back_window = years(2))
> t.Vardhman <- Quandl_Fetch(ticker = "BSE/BOM500439", look_back_window = years(2))
```

#### RSI

- Triveni Turbine Ltd

- Vardhman Holdings Ltd

There are some patterns in RSI plots, but not enough to differentiate these two companies on the ground of growth and volatility through a singular metric.

Let's see whether we can design such a metric !

#### Coppock curve

The Coppock curve or Coppock indicator is a technical analysis indicator for long-term stock market investors created by E.S.C. Coppock, first published in Barron's Magazine on October 15, 1962. This is a "behaviourally"-inspired momentum indicator.

```
coppock <- function(df) {
WMA(ROC(df, n = 11) + ROC(df, n = 14))
}
```

ROC is the Rate of Change for a given time series.

```
> mean(coppock(t.Triveni), na.rm = TRUE)
[1] 0.3807641
> mean(coppock(t.Vardhman), na.rm = TRUE)
[1] 1.711664
> mean(coppock(t.Infosys), na.rm = TRUE)
[1] -0.2949913
```

So Coppock Curve could be a good long-term momentum indicator. However, 11 and 14 numbers seem arbitrary even though they have strong "behavioural" underpinning.

#### MACD

Moving Average Convergence Divergence

It's a difference of fast-moving 12-period EMA and slow-moving 24-period EMA. You can compare this with a ZERO line, or you can construct a 9-period EMA of the MCAD itself to form a SIGNAL line for comparison.

Again, this is heavily used for short-term momentum indicator for trading, but not sure whether it fits the bill for a long-term indicator (although period could be replaced with month for long-term indicator. example - 12-period EMA becomes 12-month EMA etc.)

#### LM2Score

Linear Model Momentum Scoring

Here is how it's derived -

- Smooth by deriving 30-period EMA
- Fit a simple linear regression to the smoothed series
- Derive the momentum indicator by

```
(slope * days) / (RSE * sqrt(days))
```

`sqrt`

has been used to scale daily volatility.

- Add a volatility factor (divide by). This is just standard-deviation of the first-order discrete difference (scaled by mean)

```
volatility_measure <- function(t) {
sd(diff(t), na.rm = TRUE)/abs(mean(diff(t), na.rm = TRUE))
}
```

Complete code -

```
momentum_scoring <- function(ticker, momentum_window = 100, look_back_window = years(1)) {
t <- Quandl_Fetch(ticker, look_back_window)
old.par <- par(mfrow=c(1, 2))
par(mfrow=c(2,1))
plot(t, major.ticks="months", major.format="%b %d", main = ticker)
# Smooth it
t.smoothed <- EMA(t, n = 30)
plot(index(t.smoothed), coredata(t.smoothed),main = paste(c("EMA smoothed - ", ticker), collapse = ""))
reg <- lm(coredata(t.smoothed) ~ index(t.smoothed))
abline(reg, col = "red")
par(old.par)
round((momentum_indicator(reg, days = momentum_window) / volatility_measure(t))*100,2)
}
momentum_indicator <- function(fit, days = 100) {
(as.numeric(coef(fit)[2]) * days)/(sd(residuals(fit)) * sqrt(days))
}
volatility_measure <- function(t) {
sd(diff(t), na.rm = TRUE)/abs(mean(diff(t), na.rm = TRUE))
}
```

Now results -

- Triveni

```
> momentum_scoring(ticker = "BSE/BOM533655", momentum_window = 200, look_back_window = years(2))
[1] 0.11
```

- Vardhman

```
> momentum_scoring(ticker = "BSE/BOM500439", momentum_window = 200, look_back_window = years(2))
[1] 1.24
```

- Infosys

```
> momentum_scoring(ticker = "BSE/BOM500209", momentum_window = 200, look_back_window = years(2))
[1] -0.34
```