IBD RS historical testing

Discussion in 'Strategy Building' started by rcatch, Nov 9, 2022.

  1. Sekiyo

    Sekiyo

    I have this code for ATR normalized Relative Strength.
    What do you think about normalizing using ATR ?

    I don't like the usual XYZ/SPY because it's dominated by volatility.
    I mean if a stock is volatile (vs SPY) then the RS line will look like XYZ.

    Here we take ...
    index.atr_change = index.pts_change / index.atr(21)
    stock.atr_change = stock.pts_change / stock.atr(21)


    Then we chart the cumulative difference such as cum_diff = stock.atr_change - index.atr_change

    The purpose is to remove "beta" and keep the "alpha".

    Code:
    // This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
    // © Sekiyo
    
    //@version=6
    indicator("Cumulative Normalized Change vs Index", overlay=false)
    
    // ————— Inputs
    indexSymbol = input.symbol(title="Index Symbol", defval="BATS:SPY", tooltip="Symbol to compare against (e.g., SPY ETF)")
    
    // ————— Functions
    /// @description Calculates normalized change ratio using ATR(21)
    /// @param src The price series to analyze
    /// @returns Normalized change ratio: (current_close - previous_close) / ATR(21)
    getNormalizedChangeRatio(src) =>
        change = ta.change(src)
        atr = ta.atr(21)
        change / atr
    
    // ————— Calculations
    // Current symbol calculations
    stockRatio = getNormalizedChangeRatio(close)
    var float cumulativeStockRatio = 0
    if not na(stockRatio)
        cumulativeStockRatio += stockRatio
    
    // Index calculations (using lookahead to align timestamps)
    indexRatio = request.security(symbol=indexSymbol, timeframe=timeframe.period, expression=getNormalizedChangeRatio(close), lookahead=barmerge.lookahead_on)
    var float cumulativeIndexRatio = 0
    if not na(indexRatio)
        cumulativeIndexRatio += indexRatio
    
    // ————— Plotting
    ratio = cumulativeStockRatio - cumulativeIndexRatio
    plot(ratio, title="Cumulative Difference", color=color.blue)
    plot(ta.ema(ratio, 30))
    
    upload_2025-5-21_15-7-53.png

    It's a Resto 200K indicators.
    Be thankful.
     
    Last edited: May 21, 2025
    #11     May 21, 2025
  2. Sekiyo

    Sekiyo

    Ok, the code sucks a little.
    Can be refactored and shortened.

    Code:
    // This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
    // © Sekiyo
    
    //@version=6
    indicator("Cumulative Normalized Change vs Index", overlay=false)
    
    // Inputs
    index_symbol = input.symbol("BATS:SPY", "Index Symbol")
    sma_length = input.int(30, "SMA Length", step=1, minval=1)
    
    // Functions
    getNormalizedChange(src) =>
        change = ta.change(src)
        atr = ta.atr(21)
        change / atr
    
    // Normalized Change
    float stock_normChange = getNormalizedChange(close)
    float index_normChange = request.security(index_symbol, timeframe.period, getNormalizedChange(close), lookahead=barmerge.lookahead_on)
    
    // Cumulative Difference
    var float cumulative = 0.0
    difference = stock_normChange - index_normChange
    
    if not na(difference)
        cumulative += difference
    
    // Plotting
    cumulative_color = difference > 0 ? color.green : color.red
    plot(cumulative, "Cumulative Difference", color=cumulative_color)
    plot(ta.sma(cumulative, sma_length))
    
     
    Last edited: May 21, 2025
    #12     May 21, 2025
  3. lukwoj

    lukwoj

    This sounds simple enough. Is there any publicly available backtest?
     
    #13     Jun 16, 2025
  4. Sekiyo

    Sekiyo

    I don't know but there are studies about sharpe ratios ranking.
     
    #14     Jun 16, 2025