EN VI

Why is my Rust RSI calculation different from the TradingView indicator?

2024-03-09 23:00:14
Why is my Rust RSI calculation different from the TradingView indicator?

I am attempting to replicate the RSI indicator value from TradingView using Rust and the Mexc API, but the value displayed is incorrect. Can you help me identify what I am doing wrong?

async fn get_symbol_rsi(client: Client, symbol: &str) -> AppResult<f64> {
    let rsi_len = 14;
    let candles: Klines = client
        .get(format!(
            "https://contract.mexc.com/api/v1/contract/kline/{symbol}?interval=Min15"
        ))
        .send()
        .await?
        .json()
        .await?;

    let mut closes = candles.data.close.into_iter().rev().take(15);

    let mut gain = Vec::new();
    let mut loss = Vec::new();
    let mut prev_close = closes.next().unwrap();

    for close in closes {
        let diff = close - prev_close;

        if diff > 0.0 {
            gain.push(diff);
            loss.push(0.0);
        } else {
            gain.push(0.0);
            loss.push(diff.abs());
        }

        prev_close = close;
    }

    let avg_up = gain.iter().sum::<f64>() / rsi_len as f64;
    let avg_down = loss.iter().sum::<f64>() / rsi_len as f64;

    let rs = avg_up / avg_down;
    let rsi = 100.0 - (100.0 / (1.0 + rs));

    Ok(rsi)
}

thanks for helping.

Solution:

The main difference from what I see is that you are using a Simple Moving Average for the avg_up and avg_down variables.

TradingView uses a modified Exponential Moving Average called Relative Moving Average (RMA) for use in their Relative Strength Index (RSI) for those variables.

The difference is in the alpha variable:

Where EMA has alpha = 2 / (length + 1)

RMA has alpha = 1 / length

Below is a function for RMA in Rust:

fn rma(price_ndarray: &Array1<f32>, period: usize) -> Array1<f32>{
    let length = price_ndarray.len() - period +1;
    let mut result = Array1::<f32>::zeros(length);
    result[0] = price_ndarray.slice(s![0..period]).sum();
    for i in 1..length{
        result[i] = result[i-1]+(price_ndarray[i+period-1]-result[i-1])*(1.0/(period as f32));
    }
    
    result
}
Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login