Using S&P 500 Index Indicators to Trade Nasdaq 100 Stocks
Summary
This example applies technical signals calculated from the S&P 500 index to a universe of Nasdaq 100 stocks. It constructs separate strategies from the index's TRIX, RSI, or rate of change, then assigns liquid stocks binary exposure when paired comparisons of lagged indicator values satisfy specified conditions. The resulting weight sets are combined, cleaned, and submitted for evaluation. The source also includes a separate commented example that combines stock-level moving-average conditions with an advance-decline line.
The code supplies selected parameter sets and reports Sharpe ratios for individual variants, as well as a ratio for the commented example. It does not provide a clearly stated evaluation period, detailed performance statistics, or evidence that the parameters were selected out of sample. Applying one index signal across many stocks may also concentrate exposure around a common market driver. The examples therefore illustrate a construction method, but do not establish robustness or predictive benefit beyond the reported figures.
Key ideas
- Technical indicators computed from the S&P 500 are broadcast across Nasdaq 100 stock series.
- TRIX, RSI, and rate-of-change variants use lagged comparisons to determine liquid-stock exposure.
- The resulting strategy weights are combined before output and evaluation.
- The source reports Sharpe ratios for selected parameter sets, but gives limited context for interpreting them.
- A separate example combines moving-average filters with an advance-decline line.
Tags
Full text
# strategy-predict-NASDAQ100-use-SPX
# strategy-predict-NASDAQ100-use-SPX
## Source (MIT)
```python
# # Predicting stocks using the SPX index
#
# Predicting stocks from the NASDAQ 100 index using the SPX index and technical analysis indicators
from IPython.display import display
import xarray as xr
import qnt.data as qndata
import qnt.output as qnout
import qnt.ta as qnta
import qnt.stats as qns
def get_SPX(market_data):
index_name = 'SPX'
index_data = qndata.index.load_data(assets=[index_name], min_date='2005-01-01', forward_order=True)
spx_data = index_data.sel(asset=index_name)
spx_data = xr.align(spx_data, market_data.isel(field=0), join='right')[0]
return spx_data
def get_strategy_1(data, spx, params):
def get_trix(prices, index, periods):
result = prices.copy(True)
t = qnta.trix(index, periods)
for a in prices.asset.values:
result.loc[{"asset": a}] = t
return result
trix = get_trix(data.sel(field='close'), spx, 40)
strategy_1 = trix.shift(time=params[0]) < trix.shift(time=params[1])
strategy_2 = trix.shift(time=params[2]) > trix.shift(time=params[3])
weights = strategy_1 * strategy_2 * data.sel(field="is_liquid")
return weights.fillna(0)
def get_strategy_2(data, spx, params):
def get_rsi(prices, index, periods):
result = prices.copy(True)
r = qnta.rsi(index, periods)
for a in prices.asset.values:
result.loc[{"asset": a}] = r
return result
rsi = get_rsi(data.sel(field='close'), spx, 40)
strategy_1 = rsi.shift(time=params[0]) < rsi.shift(time=params[1])
strategy_2 = rsi.shift(time=params[2]) > rsi.shift(time=params[3])
weights = strategy_1 * strategy_2 * data.sel(field="is_liquid")
return weights.fillna(0)
def get_strategy_3(data, spx, params):
def get_roc(prices, index, periods):
result = prices.copy(True)
r = qnta.roc(index, periods)
for a in prices.asset.values:
result.loc[{"asset": a}] = r
return result
roc = get_roc(data.sel(field='close'), spx, 15)
strategy_1 = roc.shift(time=params[0]) < roc.shift(time=params[1])
strategy_2 = roc.shift(time=params[2]) > roc.shift(time=params[3])
weights = strategy_1 * strategy_2 * data.sel(field="is_liquid")
return weights.fillna(0)
data = qndata.stocks.load_ndx_data(min_date="2005-01-01")
spx = get_SPX(data)
weights_1_1 = get_strategy_1(data, spx, [142, 54, 132, 63]) # 1.0330127484868614 Sharpe Ratio
weights_1_2 = get_strategy_1(data, spx, [166, 75, 46, 24]) # 0.9591131817092265 Sharpe Ratio
weights_2 = get_strategy_2(data, spx, [159, 78, 77, 167]) # 0.8568070000760702 Sharpe Ratio
weights_3 = get_strategy_3(data, spx, [10, 27, 29, 41]) # 0.835419 Sharpe Ratio
weights_all = weights_1_1 + weights_1_2 + weights_2 + weights_3
weights = qnout.clean(output=weights_all, data=data, kind="stocks_nasdaq100")
def print_statistic(data, weights_all):
import plotly.graph_objs as go
import qnt.stats as qnstats
stats = qnstats.calc_stat(data, weights_all)
display(stats.to_pandas().tail(5))
equity_curve = stats.loc[:, "equity"]
fig = go.Figure(data=[
go.Scatter(
x=equity_curve.time.to_pandas(),
y=equity_curve,
hovertext="Equity curve",
)
])
fig.update_yaxes(fixedrange=False)
fig.show()
print_statistic(data, weights)
qnout.check(weights, data, "stocks_nasdaq100")
qnout.write(weights)
# ## Example of a strategy using technical analysis indicators
#
# The example of a strategy with a sharpe ratio of 0.9615 trading 215 financial instruments
#
# The strategy use sma, ema, adl (Advance–Decline line)
# ```python
# from IPython.display import display
# import xarray as xr
# import qnt.data as qndata
# import qnt.output as qnout
# import qnt.ta as qnta
# import qnt.stats as qns
#
# data = qndata.stocks.load_ndx_data(min_date="2005-01-01")
#
#
# def get_strategy_1(data, params):
# buy = 1
# not_trade = 0
# close = data.sel(field="close")
#
# strategy_1 = xr.where(qnta.sma(close, params[1]) > qnta.sma(close, params[0]), buy, not_trade)
# strategy_2 = xr.where(qnta.ema(close, params[2]) > qnta.ema(close, params[3]), buy, not_trade)
#
# weights = strategy_1 * strategy_2 * data.sel(field="is_liquid")
# weights = weights / 100.0
# return weights.fillna(0)
#
#
# def get_strategy_2(data, params):
# buy = 1
# not_trade = 0
# close = data.sel(field="close") * data.sel(field="is_liquid")
#
# adl = qnta.ad_line(close) * 1.0
# adl_dif = adl.shift(time=params[0]) - adl.shift(time=params[1])
# positive_trend = adl_dif > 0
# strategy_1 = xr.where(positive_trend, buy, not_trade)
#
# weights = strategy_1 * data.sel(field="is_liquid")
# return weights.fillna(0)
#
#
# weights_1 = get_strategy_1(data, [25, 40, 12, 132]) # 0.6108887689714039 Sharpe Ratio
# weights_2 = get_strategy_2(data, [34, 183]) # 0.6012686822757577
#
# weights_all = 2 * weights_1 * weights_2 - weights_1
# weights = qnout.clean(output=weights_all, data=data, kind="stocks_nasdaq100") # 0.9615
#
# # qnout.check(weights, data, "stocks_nasdaq100")
# qnout.write(weights)
# ```
```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.