Backtest Period
Markets Traded
Equities
Maximum Drawdown
Period of Rebalancing
Weekly
Return (Annual)
Sharpe Ratio
Standard Deviation (Annual)
Original paper
SSRN-id2676583.pdf600.1KB
Trading rules
- Utilize S&P 500 stocks with available Google Search Volume (GSV) data from https://www.google.com/trends
- Compute Abnormal Search Volume (ASV) as: ASVt = ln[GSVt] - ln[Med(GSVt-1, …,GSVt-8)]
- Update ASV on a weekly basis
- Go long on a stock in week t if previous week’s attention (ASVt-1) was abnormally low or unchanged, i.e., ASVt-1 ≤ 0
- Assign equal weights to stocks in the portfolio
- Rebalance portfolio weekly
Python code
Backtrader
import backtrader as bt
import numpy as np
import pandas as pd
class AbnormalSearchVolume(bt.Strategy):
params = (
('lookback', 8),
)
def __init__(self):
self.gsv_data = {} # Load Google Search Volume data here
def next(self):
asv_dict = {}
for data in self.datas:
symbol = data._name
gsv = self.gsv_data[symbol]
if len(gsv) > self.params.lookback:
gsv_t = gsv[-1]
gsv_lookback = gsv[-(self.params.lookback + 1):-1]
asv_t = np.log(gsv_t) - np.log(np.median(gsv_lookback))
asv_dict[symbol] = asv_t
# Filter stocks with ASV <= 0
selected_stocks = [k for k, v in asv_dict.items() if v <= 0]
# Equal weights for selected stocks
weight = 1 / len(selected_stocks)
# Rebalance positions
for data in self.datas:
symbol = data._name
if symbol in selected_stocks:
self.order_target_percent(data, target=weight)
else:
self.order_target_percent(data, target=0)
# Backtrader Cerebro setup, data feeds, and strategy assignment
cerebro = bt.Cerebro()
# Add S&P 500 stock data feeds and Google Search Volume data to self.gsv_data
# Set the strategy to use AbnormalSearchVolume
cerebro.addstrategy(AbnormalSearchVolume)
cerebro.run()
Please note that you need to add your own Google Search Volume data for each stock in the S&P 500 to the self.gsv_data
dictionary, as access to Google Trends data requires a custom implementation.