| Overall Statistics |
|
Total Trades
1572
Average Win
0.53%
Average Loss
-0.54%
Compounding Annual Return
15.446%
Drawdown
34.300%
Expectancy
0.300
Net Profit
243.101%
Sharpe Ratio
0.882
Probabilistic Sharpe Ratio
29.307%
Loss Rate
35%
Win Rate
65%
Profit-Loss Ratio
0.99
Alpha
0.162
Beta
-0.152
Annual Standard Deviation
0.158
Annual Variance
0.025
Information Ratio
-0.018
Tracking Error
0.234
Treynor Ratio
-0.921
Total Fees
$1477.51
Estimated Strategy Capacity
$48000000.00
Lowest Capacity Asset
D R735QTJ8XC9X
|
# https://quantpedia.com/strategies/short-interest-effect-long-only-version/
#
# All stocks from NYSE, AMEX, and NASDAQ are part of the investment universe. The short-interest ratio is used as the predictor variable.
# Stocks are sorted based on their short interest ratio, and the first percentile is held. The portfolio is equally weighted and rebalanced monthly.
class ShortInterestEffect(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2013, 1, 1)
self.SetCash(100000)
# NOTE: We use only s&p 100 stocks so it's possible to fetch short interest data from quandl.
self.symbols = [
'AAPL','MSFT','AMZN','FB','BRK.B','GOOGL','GOOG','JPM','JNJ','V','PG','XOM','UNH','BAC','MA','T','DIS','INTC','HD','VZ','MRK','PFE',
'CVX','KO','CMCSA','CSCO','PEP','WFC','C','BA','ADBE','WMT','CRM','MCD','MDT','BMY','ABT','NVDA','NFLX','AMGN','PM','PYPL','TMO',
'COST','ABBV','ACN','HON','NKE','UNP','UTX','NEE','IBM','TXN','AVGO','LLY','ORCL','LIN','SBUX','AMT','LMT','GE','MMM','DHR','QCOM',
'CVS','MO','LOW','FIS','AXP','BKNG','UPS','GILD','CHTR','CAT','MDLZ','GS','USB','CI','ANTM','BDX','TJX','ADP','TFC','CME','SPGI',
'COP','INTU','ISRG','CB','SO','D','FISV','PNC','DUK','SYK','ZTS','MS','RTN','AGN','BLK'
]
for symbol in self.symbols:
data = self.AddEquity(symbol, Resolution.Daily)
data.SetFeeModel(CustomFeeModel(self))
self.AddData(QuandlFINRA_ShortVolume, 'FINRA/FNSQ_' + symbol, Resolution.Daily)
self.Schedule.On(self.DateRules.MonthStart(self.symbols[0]), self.TimeRules.AfterMarketOpen(self.symbols[0]), self.Rebalance)
def Rebalance(self):
short_interest = {}
for symbol in self.symbols:
if self.Securities.ContainsKey('FINRA/FNSQ_' + symbol):
data = self.Securities['FINRA/FNSQ_' + symbol].GetLastData()
if data != None:
short_vol = data.GetProperty("SHORTVOLUME")
total_vol = data.GetProperty("TOTALVOLUME")
short_interest[symbol] = short_vol / total_vol
sorted_by_short_interest = sorted(short_interest.items(), key = lambda x: x[1], reverse = True)
decile = int(len(sorted_by_short_interest)/10)
long = [x[0] for x in sorted_by_short_interest[-decile:]]
# Trade execution and rebalance.
count = len(long)
stocks_invested = [x.Key.Value for x in self.Portfolio if x.Value.Invested]
for symbol in stocks_invested:
if symbol not in long:
self.Liquidate(symbol)
for symbol in long:
if self.Securities[symbol].Price != 0:
self.SetHoldings(symbol, 1 / count)
class QuandlFINRA_ShortVolume(PythonQuandl):
def __init__(self):
self.ValueColumnName = 'SHORTVOLUME' # also 'TOTALVOLUME' is accesible.
# Custom fee model.
class CustomFeeModel(FeeModel):
def GetOrderFee(self, parameters):
fee = parameters.Security.Price * parameters.Order.AbsoluteQuantity * 0.00005
return OrderFee(CashAmount(fee, "USD"))