NASDAQ-100 Weights Filtered by ATR and Smoothed Liquidity
Summary
This code example constructs NASDAQ-100 portfolio weights using a liquidity measure and an ATR-based volatility filter. It calculates 14-period ATR relative to closing price and assigns zero weight when that ratio exceeds a chosen threshold. Otherwise, each asset's share of total traded value is smoothed with a linearly weighted moving average, producing the allocation weights. The workflow loads historical index data, applies an initial liquidity treatment before the first active strategy date, cleans the output, checks it, and writes weights for a contest submission.
The code gives a concrete portfolio construction recipe and uses historical data beginning in 2005, but it does not include reported returns, risk statistics, or comparison against a benchmark. The resulting weights reflect smoothed liquidity shares rather than a return forecast, with the ATR filter excluding assets above the specified volatility ratio. The example depends on the referenced data and quant library, and its contest context does not establish out-of-sample or live trading performance.
Key ideas
- The strategy uses relative ATR to exclude assets above a volatility threshold.
- Remaining asset weights are based on traded-value shares smoothed by a linearly weighted moving average.
- The workflow prepares and validates NASDAQ-100 weights for a contest submission.
- The code shows a construction method but reports no portfolio performance results.
- The allocations reflect liquidity and volatility rules rather than an explicit return forecast.
Tags
Full text
# strategy-predict-NASDAQ100-use-atr-lwma
# strategy-predict-NASDAQ100-use-atr-lwma
## Source (MIT)
```python
# # Predicting stocks using technical indicators (atr, lwma)
# This template shows you the basic steps for taking part to the NASDAQ-100 Stock Long-Short contest.
import xarray as xr
import qnt.ta as qnta
import qnt.data as qndata
import qnt.output as qnout
import qnt.stats as qns
import xarray as xr
import qnt.ta as qnta
import qnt.backtester as qnbt
import qnt.data as qndata
def strategy2(data, wma, limit):
vol = data.sel(field="vol")
liq = data.sel(field="is_liquid")
close = data.sel(field="close")
high = data.sel(field="high")
low = data.sel(field="low")
atr = qnta.atr(high=high, low=low, close=close, ma=14)
ratio = atr / close
weights = xr.where(ratio > limit, 0, 1)
money_vol = vol * liq * close
total_money_vol = money_vol.sum(dim='asset')
money_vol_share = money_vol / total_money_vol
return qnta.lwma(money_vol_share, wma) * weights
data = qndata.stocks.load_ndx_data(min_date="2005-01-01")
weights_1 = strategy2(data, wma=135, limit=0.0205)
def get_enough_bid_for(weights_):
time_traded = weights_.time[abs(weights_).fillna(0).sum('asset') > 0]
is_strategy_traded = len(time_traded)
if is_strategy_traded:
return xr.where(weights_.time < time_traded.min(), data.sel(field="is_liquid"), weights_)
return weights_
weights_new = get_enough_bid_for(weights_1)
weights_new = weights_new.sel(time=slice("2006-01-01", None))
weights = qnout.clean(output=weights_new, data=data, kind="stocks_nasdaq100")
def print_statistic(data, weights_all):
import qnt.stats as qnstats
stats = qnstats.calc_stat(data, weights_all)
display(stats.to_pandas().tail(5))
# graph
performance = stats.to_pandas()["equity"]
import qnt.graph as qngraph
qngraph.make_plot_filled(performance.index, performance, name="PnL (Equity)", type="log")
print_statistic(data, weights)
qnout.check(weights, data, "stocks_nasdaq100")
qnout.write(weights) # to participate in the competition
weights
data
```Shown in full with attribution under the source's licence. Licence: MIT
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.