Created
December 18, 2024 17:30
-
-
Save sangelxyz/4e556af04ff03fc8d643adec3236a89b to your computer and use it in GitHub Desktop.
Tradingview RSI, RMA in rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is messy, still needs work. it will calculate the correct value with over 100points. | |
// lower v | |
///! Converted from the offical examples from. | |
/// https://www.tradingview.com/pine-script-reference/v6/ | |
#[derive(Debug, Clone)] | |
struct Series { | |
closes: Vec<f64>, | |
period: f64, | |
series_sum: Vec<f64>, | |
alpha: f64, | |
sma: Vec<f64>, | |
} | |
impl Series { | |
fn new(closes: Vec<f64>, period: usize) -> Self { | |
let period = period as f64; | |
Series { | |
closes, | |
period, | |
series_sum: Vec::new(), | |
sma: Vec::new(), | |
alpha: 1_f64 / period, | |
} | |
} | |
/// Returns the last value of series_sum or 0.0 if it's empty | |
// fn previous_sum(&self) -> f64 { | |
// *self.series_sum.last().unwrap_or(&0.0) | |
// } | |
// pine_rma(src, length) => | |
// alpha = 1/length | |
// sum = 0.0 | |
// sum := na(sum[1]) ? ta.sma(src, length) : alpha * src + (1 - alpha) * nz(sum[1]) | |
fn pine_rma(&self, source: &Vec<f64>) -> f64 { | |
let mut sum = 0.0; | |
for (index, &src) in source.iter().enumerate() { | |
// On the first iteration, use a simple moving average (SMA) | |
let prev_sum = if index == 0 { 0.0 } else { sum }; // or use self.previous_sum() if you have that method | |
let sumd = if prev_sum == 0.0 { | |
self.clone().pine_sma(&source) // assuming self.pine_sma() is correct | |
} else { | |
self.alpha * src + (1_f64 - self.alpha) * prev_sum | |
}; | |
sum = sumd; // Update sum for the next iteration | |
} | |
sum | |
} | |
///! pine_rsi(x, y) => | |
// u = math.max(x - x[1], 0) // upward ta.change | |
// d = math.max(x[1] - x, 0) // downward ta.change | |
// rs = ta.rma(u, y) / ta.rma(d, y) | |
// res = 100 - 100 / (1 + rs) | |
// res | |
pub fn pine_rsi(&self) -> f64 { | |
let mut prev = 0.0; | |
let mut u = Vec::new(); | |
let mut d = Vec::new(); | |
// Calculate upward and downward changes | |
for &c in &self.closes { | |
let up = f64::max(c - prev, 0.0); | |
let down = f64::max(prev - c, 0.0); | |
u.push(up); | |
d.push(down); | |
prev = c; // Update the previous close value | |
} | |
// Calculate RMA for upward and downward changes | |
let rma_u = self.pine_rma(&u); | |
let rma_d = self.pine_rma(&d); | |
// Calculate RSI | |
let rs = if rma_d == 0.0 { 0.0 } else { rma_u / rma_d }; | |
let rsi = 100.0 - 100.0 / (1.0 + rs); | |
rsi | |
} | |
// fn pine_rsi(self) -> f64 { | |
// let prev = None; | |
// let u: Vec<f64> = self.closes.clone().iter().map(|c| { | |
// let prev = if let Some(p) = prev { p } else { 0.0 }; | |
// f64::max(c - prev, 0_f64) | |
// }).collect(); | |
// let prev = None; | |
// let d: Vec<f64> = self.closes.clone().iter().map(|c| { | |
// let prev = if let Some(p) = prev { p } else { 0.0 }; | |
// f64::max(prev - c, 0_f64) | |
// }).collect(); | |
// let rs = self.clone().pine_rma(&u) / self.clone().pine_rma(&d); | |
// println!("ssss{}", self.clone().pine_rma(&u)); | |
// let res = 100_f64 - 100_f64 / (1_f64 + rs); | |
// res | |
// } | |
// fn pine_rma2(&mut self, close: f64) { | |
// // Access the last value of series_sum without calling another method | |
// let prev_sum = 0.0; | |
// // Calculate the RMA using the previous value and the current close | |
// let sum = if *prev_sum == 0.0 { self.pine_sma() } else { self.alpha * close + (1_f64 - self.alpha) * prev_sum }; | |
// // Push the new sum into the series_sum vector | |
// self.series_sum.push(sum); | |
// } | |
// close[i] works diffrently, it goes back | |
fn get_close(self, back_period: usize) -> f64 { | |
let len = self.series_sum.len(); // TODO: this should be an index of somekind, needs to be updated. | |
if back_period > len { return 0_f64 } | |
let close = *self.closes.get(len-back_period).unwrap_or(&0_f64); | |
close | |
} | |
///! Converted from example | |
// pine_sma(close, period) => | |
// sum = 0.0 | |
// for i = 0 to period - 1 | |
// sum := sum + close[i] / period | |
// fn pine_sma(&mut self, src: &Vec<f64>) -> f64 { | |
// let mut sum = 0.0; | |
// let last_14: Vec<f64> = src.iter().rev().take(self.period as usize).cloned().collect(); | |
// let sma = last_14.iter().sum::<f64>() / self.period; | |
// sma | |
// } | |
fn pine_sma(&mut self, src: &Vec<f64>) -> f64 { | |
let mut sum = 0.0; | |
let period = self.period as usize; | |
let len = src.len(); | |
if len < period { | |
return 0.0; // Or handle cases where `src` has fewer than `period` elements | |
} | |
for i in 0..period { | |
// Use reverse indexing to access the last `period` elements | |
sum += src[len - 1 - i] / self.period; | |
} | |
sum | |
} | |
// fn series_rma(&mut self) { | |
// let closes = self.closes.clone(); // Clone the vector to avoid borrowing `self` | |
// for close in closes { | |
// self.pine_rma(close); | |
// println!("{:?}", self.pine_sma()); | |
// } | |
// } | |
} | |
// Get RMA for all of series. | |
// rsi takes closes. | |
// u & d are seperate series, they hold rma data from a calculation. | |
// | |
// fn pine_rsi(series: &mut Series) { | |
// let closes = [1.2, 2.3, 3.2, 2.3, 3.2, 2.3, 3.2, 2.3, 3.2, 2.3, 3.2, 2.3, 3.2, 2.3, 3.2, 2.3, 3.2, 2.3, 1.1, 3.2, 2.3, 3.2].to_vec(); | |
// // let mut series = Series::new(closes.clone(), 14); | |
// let series_index = series.series_sum.len(); | |
// let current_close = series.closes.get(series_index).unwrap_or(&0.0); | |
// let prev_close = series.closes.get(series_index-1).unwrap_or(&0.0); | |
// // | |
// Series::new(,14) | |
// let u = f64::max(current_close - prev_close, 0_f64); //Upward ta max of current_close - previous_close and 0 | |
// let d = f64::max(prev_close - current_close, 0_f64); // Downward ta max of previous close - current_close and 0 | |
// let res = self.rma(u) | |
// } | |
fn main() { | |
let closes = [261.16, 260.05, 260.53, 259.67, 263.62, 262.99, 258.87, 251.12, 253.92, 254.85, 242.68, 220.11, 211.99, 212.08, 216.52, 212.42, 205.76, 207.3, 197.36, 200.84, 205.66, 218.51, 219.96, 219.27, 222.18, 222.11, 209.98, 214.65, 223.71, 237.41, 242.84, 233.59, 234.3, 235.6, 241.2, 234.21, 235.45, 236.08, 246.72, 244.14, 240.08, 238.83, 235.58, 238.72, 239.37, 242.64, 243.84, 239.74, 237.01, 239.29, 251.05, 253.5, 252.08, 257.22, 247.14, 254.5, 252.54, 256.61, 261.44, 253.18, 248.48, 248.42, 238.45, 237.93, 237.49, 240.45, 234.96, 233.94, 227.22, 218.89, 219.91, 215.55, 211.88, 212.19, 208.8, 209.14, 207.83, 182.63, 183.25, 190.93, 191.59, 187.29, 188.86, 187.91, 181.06, 185.1, 187.58, 189.56, 193.57, 188.13, 184.02, 188.71, 200.45, 199.95, 193.76, 194.77, 197.41, 191.97, 199.4, 199.73, 202.04, 201.88, 202.64, 188.14, 180.74, 176.54, 178.65, 175.34, 177.77, 177.54, 169.48, 162.5, 163.57, 173.8, 171.32, 175.66, 172.82, 170.83, 172.63, 177.67, 179.83, 175.79, 175.22, 166.63, 168.38, 171.11, 164.9, 172.98, 176.88, 171.76, 174.6, 171.05, 161.48, 157.11, 155.45, 149.93, 147.05, 142.05, 144.68, 162.13, 170.18, 168.29, 194.05, 183.28, 179.99, 180.01, 181.19, 184.76, 177.81, 174.72, 171.97, 168.47, 171.89, 177.55, 173.99, 174.84, 177.46, 174.95, 186.6, 180.11, 173.74, 179.24, 176.75, 176.19, 178.79, 178.08, 176.29, 174.77, 175.0, 177.94, 177.48, 173.79, 170.66, 177.29, 182.47, 178.01, 187.44, 184.86, 181.57, 183.01, 182.58, 187.35, 196.37, 197.42, 197.88, 209.86, 231.26, 246.39, 251.52, 252.94, 262.33, 263.26, 241.03, 248.23, 252.64, 256.56, 248.5, 249.23, 239.2, 251.51, 246.38, 215.99, 220.25, 219.8, 232.1, 222.62, 232.07, 216.86, 207.67, 198.88, 200.64, 191.76, 198.84, 200.0, 197.49, 207.83, 201.38, 214.14, 216.12, 222.72, 221.1, 223.27, 210.66, 220.32, 213.21, 209.21, 205.75, 206.28, 214.11, 210.6, 219.41, 230.17, 210.73, 216.27, 226.17, 228.13, 229.81, 230.29, 226.78, 227.87, 227.2, 243.92, 238.25, 250.0, 254.27, 257.02, 254.22, 260.46, 261.63, 258.02, 249.02, 240.66, 250.08, 240.83, 244.5, 241.05, 238.77, 217.8, 219.16, 219.57, 221.33, 220.89, 220.7, 218.85, 217.97, 213.65, 260.48, 269.19, 262.51, 259.52, 257.55, 249.85, 248.98, 242.84, 251.44, 288.53, 296.91, 321.22, 350.0, 328.49, 330.24, 311.18, 320.72, 338.74, 346.0, 342.03, 339.64, 352.56, 338.59, 338.23, 332.89, 345.16, 357.09, 351.42, 357.93, 369.49, 389.22, 389.79].to_vec(); | |
//for i in 0..closes.len() { | |
let mut series = Series::new(closes.clone()[closes.len()-130..closes.len()].to_vec(), 14); | |
println!("{:?}", series.pine_rsi()) | |
//} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment