Indicators
Combining Indicators
Create Subscriptions
You need to subscribe to some market data in order to calculate indicator values.
qb = QuantBook() symbol = qb.add_equity("SPY").symbol
Create Indicator Timeseries
You need to subscribe to some market data and create a composite indicator in order to calculate a timeseries of indicator values. In this example, use a 10-period SimpleMovingAverage
of a 10-period RelativeStrengthIndex
indicator.
# Create 10-period RSI and 10-period SMA indicator objects. rsi = RelativeStrengthIndex(10) sma = SimpleMovingAverage(10) # Create a composite indicator by feeding the value of 10-period RSI to the 10-period SMA indicator. sma_of_rsi = IndicatorExtensions.of(sma, rsi)
Follow these steps to create an indicator timeseries:
- Get some historical data.
- Create a
RollingWindow
for each attribute of the indicator to hold their values. - Attach a handler method to the indicator that updates the
RollingWindow
objects. - Iterate the historical market data to update the indicators and the
RollingWindow
s. - Populate a
DataFrame
with the data in theRollingWindow
objects.
# Request historical trading data with the daily resolution. history = qb.history[TradeBar](symbol, 70, Resolution.DAILY)
In this example, save 50 data points.
# Create a window dictionary to store RollingWindow objects. window = {} # Store the RollingWindow objects, index by key is the property of the indicator. window['time'] = RollingWindow[DateTime](50) window["SMA Of RSI"] = RollingWindow[float](50) window["rollingsum"] = RollingWindow[float](50)
# Define an update function to add the indicator values to the RollingWindow object. def update_sma_of_rsi_window(sender: object, updated: IndicatorDataPoint) -> None: indicator = sender window['time'].add(updated.end_time) window["SMA Of RSI"].add(updated.value) window["rollingsum"].add(indicator.rolling_sum.current.value) sma_of_rsi.updated += UpdateSmaOfRsiWindow
When the indicator receives new data, the preceding handler method adds the new IndicatorDataPoint
values into the respective RollingWindow
.
for bar in history: # Update the base indicators, the composite indicator will update automatically when the base indicator is updated. rsi.update(bar.end_time, bar.close)
sma_of_rsi_dataframe = pd.DataFrame(window).set_index('time')
![Historical data of 10-day SMA of 10-day RSI](https://cdn.quantconnect.com/i/tu/indicator-composite-py-classic-smaofrsi.png)
Examples
The following examples demonstrate some common practices for researching with combining indicators.
Example 1: Plot Standard Deviation Of Return
The following example demonstrates a quick backtest to testify the effectiveness of a Standard Deviation On Return mean-reversal under the research enviornment.
# Instantiate the QuantBook instance for researching. qb = QuantBook() # Request SPY data to work with the indicator. symbol = qb.add_equity("SPY").symbol # Get the historical data for trading. history = qb.history(symbol, 500, Resolution.DAILY).close.unstack(0) history = history.groupby(history.index.date).sum() # Create the SD on Return with parameters to be studied. roc = RateOfChange(1) sd = StandardDeviation(252) indicator = IndicatorExtensions.of(sd, roc) # Update and obtain the indicator value def update(row): roc.update(row.name, row.iloc[0]) return indicator.current.value indicator_dataframe = history.apply(update, axis=1).iloc[252:] indicator_dataframe.plot(title=f"Return SD of {symbol}", ylabel="%", xlabel="Time")