mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-07-27 17:27:43 +00:00
91 lines
5.2 KiB
Plaintext
91 lines
5.2 KiB
Plaintext
// Licensed under the Apache License, Version 2.0
|
|
// © mihakralj
|
|
//@version=6
|
|
indicator("Relative Strength Xtra (RSX)", "RSX", overlay=false)
|
|
|
|
//@function Calculates RSX (Relative Strength Xtra) using integrated JMA smoothing
|
|
//@param src Source series to calculate RSX for
|
|
//@param len Lookback period for RSX calculation
|
|
//@returns RSX value measuring momentum with reduced noise
|
|
rsx(series float src,simple int len)=>
|
|
if len<=0
|
|
runtime.error("Length must be greater than 0")
|
|
float u=math.max(src-src[1],0),d=math.max(src[1]-src,0)
|
|
var simple float power=0.5
|
|
var simple float PHASE_VALUE=0.5
|
|
var simple float BETA=power*(len-1)/((power*(len-1))+2)
|
|
var simple float LEN1=math.max((math.log(math.sqrt(0.5*(len-1)))/math.log(2.0))+2.0,0)
|
|
var simple float POW1=math.max(LEN1-2.0,0.5)
|
|
var simple float LEN2=math.sqrt(0.5*(len-1))*LEN1
|
|
var simple float POW1_RECIPROCAL=1.0/POW1
|
|
var simple float AVG_VOLTY_ALPHA=2.0/(math.max(4.0*len,65)+1.0)
|
|
var simple float DIV=1.0/(10.0+10.0*(math.min(math.max(len-10,0),100))/100.0)
|
|
var float upperBand_state_up=na,var float lowerBand_state_up=na
|
|
var float ma1_state_up=na,var float jma_state_up=na
|
|
var float vSum_state_up=0.0,var float det0_state_up=0.0,var float det1_state_up=0.0
|
|
var float avgVolty_state_up=na,var float smoothUp=na
|
|
var volty_array_state_up=array.new_float(11,0.0)
|
|
var float upperBand_state_down=na,var float lowerBand_state_down=na
|
|
var float ma1_state_down=na,var float jma_state_down=na
|
|
var float vSum_state_down=0.0,var float det0_state_down=0.0,var float det1_state_down=0.0
|
|
var float avgVolty_state_down=na,var float smoothDown=na
|
|
var volty_array_state_down=array.new_float(11,0.0)
|
|
if not na(u)
|
|
float del1_up=u-nz(upperBand_state_up,u),float del2_up=u-nz(lowerBand_state_up,u)
|
|
float volty_up=math.abs(del1_up)==math.abs(del2_up)?0.0:math.max(math.abs(del1_up),math.abs(del2_up))
|
|
array.unshift(volty_array_state_up,nz(volty_up,0.0))
|
|
array.pop(volty_array_state_up)
|
|
if not na(volty_up)
|
|
vSum_state_up:=vSum_state_up+(volty_up-array.get(volty_array_state_up,10))*DIV
|
|
avgVolty_state_up:=nz(avgVolty_state_up,vSum_state_up)+AVG_VOLTY_ALPHA*(vSum_state_up-nz(avgVolty_state_up,vSum_state_up))
|
|
float rvolty_up=math.min(math.max(nz(avgVolty_state_up,0)>0?nz(volty_up,0.0)/nz(avgVolty_state_up,1.0):1.0,1.0),math.pow(LEN1,POW1_RECIPROCAL))
|
|
float pow2_up=math.pow(rvolty_up,POW1)
|
|
float Kv_up=math.pow(LEN2/(LEN2+1),math.sqrt(pow2_up))
|
|
upperBand_state_up:=del1_up>0?u:u-Kv_up*del1_up
|
|
lowerBand_state_up:=del2_up<0?u:u-Kv_up*del2_up
|
|
float alpha_up=math.pow(BETA,pow2_up)
|
|
float alphaSquared_up=alpha_up*alpha_up,float oneMinusAlpha_up=1.0-alpha_up
|
|
float oneMinusAlphaSquared_up=oneMinusAlpha_up*oneMinusAlpha_up
|
|
ma1_state_up:=u+(alpha_up*(nz(ma1_state_up,u)-u))
|
|
det0_state_up:=(u-ma1_state_up)*(1-BETA)+BETA*nz(det0_state_up,0)
|
|
float ma2_up=ma1_state_up+(PHASE_VALUE*det0_state_up)
|
|
det1_state_up:=((ma2_up-nz(jma_state_up,u))*oneMinusAlphaSquared_up)+(alphaSquared_up*nz(det1_state_up,0))
|
|
jma_state_up:=nz(jma_state_up,u)+det1_state_up
|
|
smoothUp:=jma_state_up
|
|
if not na(d)
|
|
float del1_down=d-nz(upperBand_state_down,d),float del2_down=d-nz(lowerBand_state_down,d)
|
|
float volty_down=math.abs(del1_down)==math.abs(del2_down)?0.0:math.max(math.abs(del1_down),math.abs(del2_down))
|
|
array.unshift(volty_array_state_down,nz(volty_down,0.0))
|
|
array.pop(volty_array_state_down)
|
|
if not na(volty_down)
|
|
vSum_state_down:=vSum_state_down+(volty_down-array.get(volty_array_state_down,10))*DIV
|
|
avgVolty_state_down:=nz(avgVolty_state_down,vSum_state_down)+AVG_VOLTY_ALPHA*(vSum_state_down-nz(avgVolty_state_down,vSum_state_down))
|
|
float rvolty_down=math.min(math.max(nz(avgVolty_state_down,0)>0?nz(volty_down,0.0)/nz(avgVolty_state_down,1.0):1.0,1.0),math.pow(LEN1,POW1_RECIPROCAL))
|
|
float pow2_down=math.pow(rvolty_down,POW1)
|
|
float Kv_down=math.pow(LEN2/(LEN2+1),math.sqrt(pow2_down))
|
|
upperBand_state_down:=del1_down>0?d:d-Kv_down*del1_down
|
|
lowerBand_state_down:=del2_down<0?d:d-Kv_down*del2_down
|
|
float alpha_down=math.pow(BETA,pow2_down)
|
|
float alphaSquared_down=alpha_down*alpha_down,float oneMinusAlpha_down=1.0-alpha_down
|
|
float oneMinusAlphaSquared_down=oneMinusAlpha_down*oneMinusAlpha_down
|
|
ma1_state_down:=d+(alpha_down*(nz(ma1_state_down,d)-d))
|
|
det0_state_down:=(d-ma1_state_down)*(1-BETA)+BETA*nz(det0_state_down,0)
|
|
float ma2_down=ma1_state_down+(PHASE_VALUE*det0_state_down)
|
|
det1_state_down:=((ma2_down-nz(jma_state_down,d))*oneMinusAlphaSquared_down)+(alphaSquared_down*nz(det1_state_down,0))
|
|
jma_state_down:=nz(jma_state_down,d)+det1_state_down
|
|
smoothDown:=jma_state_down
|
|
float rs=smoothDown==0?0:smoothUp/smoothDown
|
|
100-(100/(1+rs))
|
|
|
|
// ---------- Main loop ----------
|
|
|
|
// Inputs
|
|
i_length = input.int(14, "Length", minval=1)
|
|
i_source = input.source(close, "Source")
|
|
|
|
// Calculation
|
|
rsx_value = rsx(i_source, i_length)
|
|
|
|
// Plot
|
|
plot(rsx_value, "RSX", color=color.yellow, linewidth=2)
|