Original paper
Abstract
Previous research describes the net share issuance anomaly in U.S. stocks as pervasive, both in size-based sorts and in cross-section regressions. As a further test of its pervasiveness, this paper undertakes an in-depth study of share issuance effects in the Australian equity market. The anomaly is observed in all size stocks except micro stocks. For example, equal weighted portfolios of non-issuing big stocks outperform portfolios of high issuing big stocks by an average of 0.84% per month over 1990–2009. This outperformance survives risk adjustment and appears to subsume the asset growth effect in Australian stock returns.
Keywords:Â share issuance, asset pricing, cross-sectional return, asset growth, mispricing
Trading rules
- Investment universe: Australian exchange stocks
- Stock categorization:
- Micro stocks: lowest 30% of firms by market capitalization
- Small stocks: middle 40% of firms by market capitalization
- Big stocks: largest 30% of firms by market capitalization
- Focus on Big stocks for the trading strategy
- Portfolio formation timeline: end of each December of year t-1
- Net share issuance calculation: natural log of adjusted shares at the end of June of year t-1 minus the natural log of adjusted shares at the end of June of year t-2
- Portfolio sorting based on net issuance variables:
- Negative net issuance:
- NegLow: most negative net issuance firms (50th percentile)
- NegHigh: other negative issuance firms
- Zero net issuance: Zeros portfolio
- Positive net issuance quintiles:
- PosLow: 0-20th percentile
- Pos2: 20-40th percentile
- Pos3: 40-60th percentile
- Pos4: 60-80th percentile
- PosHigh: 80-100th percentile
- Investment strategy:
- Go long on Zeros portfolio stocks (zero share issuance)
- Short stocks in PosHigh portfolio (highest share issuance)
- Stock weighting: equal weights
- Portfolio rebalancing: yearly
Python code
Backtrader
import backtrader as bt
import numpy as np
class ShareIssuanceStrategy(bt.Strategy):
params = dict(
rebalance_month=12,
)
def __init__(self):
self.month_counter = 0
def next(self):
# Rebalance yearly
if self.data.datetime.date().month == self.params.rebalance_month and self.month_counter:
self.rebalance_portfolio()
self.month_counter += 1
def rebalance_portfolio(self):
# Categorize stocks by market cap
market_caps = sorted([(stk, stk.market_cap) for stk in self.datas], key=lambda x: x[1])
num_stocks = len(market_caps)
big_stocks = market_caps[int(num_stocks * 0.7):]
# Calculate net share issuance
net_issuance = []
for stk, market_cap in big_stocks:
net_issuance.append(
(stk, np.log(stk.adj_shares[-6]) - np.log(stk.adj_shares[-18]))
)
# Sort stocks into portfolios
neg_low, neg_high, zeros, pos_low, pos2, pos3, pos4, pos_high = [], [], [], [], [], [], [], []
for stk, issuance in net_issuance:
if issuance < 0:
neg_low.append(stk) if issuance <= np.percentile([i[1] for i in net_issuance if i[1] < 0], 50) else neg_high.append(stk)
elif issuance == 0:
zeros.append(stk)
else:
percentile = np.percentile([i[1] for i in net_issuance if i[1] > 0], [20, 40, 60, 80])
if issuance <= percentile[0]:
pos_low.append(stk)
elif issuance <= percentile[1]:
pos2.append(stk)
elif issuance <= percentile[2]:
pos3.append(stk)
elif issuance <= percentile[3]:
pos4.append(stk)
else:
pos_high.append(stk)
# Long on Zeros portfolio stocks and short on PosHigh portfolio stocks
for stk in self.datas:
if stk in zeros:
self.order_target_percent(stk, target=1 / len(zeros))
elif stk in pos_high:
self.order_target_percent(stk, target=-1 / len(pos_high))
else:
self.order_target_percent(stk, target=0)
cerebro = bt.Cerebro()
# Add Australian exchange stocks data feed to cerebro
# Add ShareIssuanceStrategy to cerebro
cerebro.run()