Screening Stocks by Price Range, Convertible Bonds, and Turnover
Summary
The screen selects stocks whose daily high-to-low range is at least 1% of the low price, whose associated unredeemed convertible bond has a nonempty name, and whose prior-day actual turnover lies between 3% and 28%. The article interprets the range as a sign of price movement, the bond condition as a possible indicator of company strength, and the turnover band as a way to focus on stocks with some market activity.
It cautions that restrictive filters can exclude worthwhile candidates and that turnover that is too high or too low may affect a stock’s attractiveness. It suggests adapting turnover thresholds to market conditions and combining the screen with technical indicators. The document provides formula and Python examples, but the code’s turnover calculation and security universe filters may not match the stated rule exactly. It offers no backtest or performance evidence, and the convertible-bond condition alone does not demonstrate company quality.
Key ideas
- The screen requires a daily high-to-low range of at least 1% of the low price.
- It filters for a nonempty name on an unredeemed convertible bond and prior-day turnover from 3% to 28%.
- The article suggests adjusting turnover criteria to market conditions and adding technical measures.
- The examples are not validated with performance results, and the bond-name filter does not prove financial strength.
Tags
Full text
# Researching the Momentum Factor
<a href="https://www.quantrocket.com"><img alt="QuantRocket logo" src="https://www.quantrocket.com/assets/img/notebook-header-logo.png"></a><br>
<a href="https://www.quantrocket.com/disclaimer/">Disclaimer</a>
***
[Moonshot Intro](Introduction.ipynb) › Part 3: Momentum Factor Research
***
# Researching the Momentum Factor
Momentum investing says that excess returns can be generated by buying recent winners and selling recent losers. In this notebook we will research the momentum factor on our universe of demo stocks. This will help us determine whether we have a profitable idea before turning to a full backtest.
First, load your historical data into pandas.
```python
from quantrocket import get_prices
prices = get_prices("usstock-free-1d", universes="usstock-free", start_date="2018-01-01", end_date="2020-04-01", fields=["Close"])
prices.head()
```
Next, we use closing prices to calculate our momentum factor. We calculate momentum using a twelve-month window but excluding the most recent month, as commonly recommended by academic papers.
```python
closes = prices.loc["Close"]
MOMENTUM_WINDOW = 252 # 12 months = 252 trading days
RANKING_PERIOD_GAP = 22 # 1 month = 22 trading days
earlier_closes = closes.shift(MOMENTUM_WINDOW)
later_closes = closes.shift(RANKING_PERIOD_GAP)
momentum_returns = (later_closes - earlier_closes) / earlier_closes
```
Now that we have the twelve-month returns, we calculate the next day returns:
```python
next_day_returns = closes.ffill().pct_change().shift(-1)
```
To see if the twelve-month returns predict next-day returns, we will split the twelve-month returns into bins and look at the mean next-day return of each bin. To do this, we first need to stack our wide-form DataFrames into Series.
```python
momentum_returns = momentum_returns.stack(dropna=False)
next_day_returns = next_day_returns.stack(dropna=False)
```
Use pandas' `qcut` function to create the bins:
```python
import pandas as pd
# For a very small demo universe, you might only want 2 quantiles
num_bins = 2
bins = pd.qcut(momentum_returns, num_bins)
```
Now group the next day returns by momentum bin and plot the mean return:
```python
next_day_returns.groupby(bins).mean().plot(kind="bar", title="Next-day return by 12-month momentum bin");
```
For a predictive factor, the higher quantiles should perform better than the lower quantiles.
***
## *Next Up*
Part 4: [Moonshot Strategy Code](Part4-Moonshot-Strategy-Code.ipynb)
Shown in full with attribution under the source's licence. Licence: Apache-2.0
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.