The Ringer aka Adaptive RSMK Indicator for ThinkorSwim

wtf_dude

Active member
Just something I threw together when fiddling around with the RSMK and relative strength in general. All the RSMK (Markos Katsanos' relative strength) does is check your stock's performance against a benchmark index. The drawback is that you may not know at any given time what index is performing the best (qqq vs spy, etc). With this version, you can put your stock "through the ringer" by entering up to 6 indices to check performance against. The indicator will switch to checking strength against the top performer automatically. An additional recommendation I'll give is to make the indicator a watchlist column (copy pasting the code is fine) and using it to sort a watchlist to pick the best performers over your chosen time frame.

Code:
# The Ringer v1.0 - 9.6.20 by WTF_Dude
# One drawback of the regular RSMK is that you only choose one index to compare the stock or fund to.
# The best perorming index can constantly shift. So the Ringer allows you to enter up to 6 indexes
# to compare performance against. The indicator will constantly shift to checking the relative performance
# against the top index of the chosen 6. This indicator can be used as a watchlist column as well.

# based on study from Markos Katsanos and TD Ameritrade IP Company, Inc. (c) 2020
#

declare lower;

input security1 = "SPY";  # Main benchmark
input security2 = "QQQ";  # tech heavy
input security3 = "SLV";  # commodity or alt currency
input security4 = "ITB";  # real estate or homebuilders
input security5 = "IEF";  # safe haven
input security6 = "EEM";  # emerging markets

def a = close("security1") - close("security1")[90];
def b = close("security2") - close("security2")[90];
def c = close("security3") - close("security3")[90];
def d = close("security4") - close("security4")[90];
def e = close("security5") - close("security5")[90];
def f = close("security6") - close("security6")[90];


input rsLength = 90;
# Consider not only the common market time frames, but also
# calculating how many days back the last market bottom was
# and checking performance since then

input averageLength = 3;
# 3 for the average is used to help eliminate market noise, per the original indicator


def logRatio = Log(close / close(security1));
def RelativeStrength = 100 * ExpAverage(logRatio - logRatio[rsLength], averageLength);

def logRatio1 = Log(close / close(security2));
def RelativeStrength1 = 100 * ExpAverage(logRatio1 - logRatio1[rsLength], averageLength);

def logRatio2 = Log(close / close(security3));
def RelativeStrength2 = 100 * ExpAverage(logRatio2 - logRatio2[rsLength], averageLength);

def logRatio3 = Log(close / close(security4));
def RelativeStrength3 = 100 * ExpAverage(logRatio3 - logRatio3[rsLength], averageLength);

def logRatio4 = Log(close / close(security5));
def RelativeStrength4 = 100 * ExpAverage(logRatio4 - logRatio4[rsLength], averageLength);

def logRatio5 = Log(close / close(security5));
def RelativeStrength5 = 100 * ExpAverage(logRatio4 - logRatio4[rsLength], averageLength);


plot relativestrengthu = if relativestrength is less than relativestrength1 and relativestrength2 and relativestrength3 and relativestrength4  and relativestrength5 then relativestrength else if relativestrength1 is less than relativestrength and relativestrength2 and relativestrength3 and relativestrength4  and relativestrength5  then relativestrength1 else if relativestrength2 is less than relativestrength and relativestrength1 and relativestrength3 and relativestrength4  and relativestrength5 then relativestrength2 else if relativestrength3 is less than relativestrength and relativestrength1 and relativestrength2 and relativestrength4  and relativestrength5  then relativestrength3 else if relativestrength4 is less than relativestrength1 and relativestrength2 and relativestrength3 and relativestrength5 then relativestrength4 else relativestrength5;




RelativeStrengthu.SetPaintingStrategy(PaintingStrategy.Histogram);
RelativeStrengthu.DefineColor("Positive", Color.UPTICK);
RelativeStrengthu.DefineColor("Negative", Color.DOWNTICK);
RelativeStrengthu.AssignValueColor(if RelativeStrengthu >= 0 then RelativeStrengthu.Color("Positive") else RelativeStrengthu.Color("Negative"));

plot ZeroLine = 0;
ZeroLine.SetDefaultColor(GetColor(7));
 
Last edited:

wtf_dude

Active member
Just updated my ringer sector picks for anybody interested (Based on performance since last month's correction)

VUG= broad market (vanguard growth)
SMH= strong sector (semis)
ITB = real estate (homebuilders)
KWEB= foreign/emerging (Chinese internet)
SGDJ =gold/silver (jr gold miners)
UUP = "cash" position (US dollar)

Also using 45 days as the time setting, for the moment
 
Last edited:

lmk99

Member
@wtf_dude This is awesome. I haven't used an RSMK indicator before, so I apologize if this is an obvious question: is it possible for this study to start plotting at market open or sooner near market open instead of starting to plot at 11am (I only see the plot appear at 11am onwards, at least, that is what I see and I use a 1min chart)? Or is the idea that it wouldn't make sense to have it plot before 11am because of the time needed to establish the relative strength of the indexes for the day?
 

wtf_dude

Active member
@wtf_dude This is awesome. I haven't used an RSMK indicator before, so I apologize if this is an obvious question: is it possible for this study to start plotting at market open or sooner near market open instead of starting to plot at 11am (I only see the plot appear at 11am onwards, at least, that is what I see and I use a 1min chart)? Or is the idea that it wouldn't make sense to have it plot before 11am because of the time needed to establish the relative strength of the indexes for the day?
hmmm I'm not an intraday trader for the most part so somebody with more expertise than me would need to fiddle around with it to check if this is possible. The one minute charts move much different than even a 15 min. You do need to consider though that if you're doing a relative performance comparison you need a track record to compare against. So even on a 1 minute chart, you won't have any idea which index is winning out until the 60 seconds is up (This would be a repainting indicator) If it's starting at 11, maybe it needs 30 minutes as a minimum to complete the calculation? Anybody on here is free to check.
 

wtf_dude

Active member
How can I make this into a column code?
Just put this code in. Don't worry about what the number is itself, just click the column to sort by relative strength. Ive been using it for about a year now and it kicks ass. If the number is bright, it means relative strength is improving, vice versa for dark number. I continually update what indexes im using every week or 2 depending on whats doing best.
Code:
# TheRinger by WTF_Dude
# Modification of Markos Katsano's RSMK
# Watchlist column
# The regular RSMK requires picking an index to compare a stock's relative performance. With the Ringer you choose 5 indices and the stock will constantly compare itself relative to the best performing index at any given time. Note that a limitation is that the relative performance of any of the CHOSEN indexes will display as zero.

declare lower;

input security1 = "SPY";  # the benchmark
input security2 = "XOP";  # the 100's
input security3 = "JO";  # best performing commodity
input security4 = "XHB";  # real estate or homebuilders
input security5 = "EFR";  # safe haven treasuries
input security6 = "EEM"; # emerging markets
input rsLength = 21;

def a = close("security1") - close("security1")[rsLength];
def b = close("security2") - close("security2")[rsLength];
def c = close("security3") - close("security3")[rsLength];
def d = close("security4") - close("security4")[rsLength];
def e = close("security5") - close("security5")[rsLength];
def f = close("security6") - close("security6")[rsLength];



#3 is used to eliminate short term noise per Katsanos
def averageLength = 3;

def logRatio = Log(close / close(security1));
def RelativeStrength = 100 * ExpAverage(logRatio - logRatio[rsLength], averageLength);

def logRatio1 = Log(close / close(security2));
def RelativeStrength1 = 100 * ExpAverage(logRatio1 - logRatio1[rsLength], averageLength);

def logRatio2 = Log(close / close(security3));
def RelativeStrength2 = 100 * ExpAverage(logRatio2 - logRatio2[rsLength], averageLength);

def logRatio3 = Log(close / close(security4));
def RelativeStrength3 = 100 * ExpAverage(logRatio3 - logRatio3[rsLength], averageLength);

def logRatio4 = Log(close / close(security5));
def RelativeStrength4 = 100 * ExpAverage(logRatio4 - logRatio4[rsLength], averageLength);

def logRatio5 = Log(close / close(security5));
def RelativeStrength5 = 100 * ExpAverage(logRatio4 - logRatio4[rsLength], averageLength);


plot relativestrengthu = round(if relativestrength is less than relativestrength1 and relativestrength2 and relativestrength3 and relativestrength4  and relativestrength5 then relativestrength else if relativestrength1 is less than relativestrength and relativestrength2 and relativestrength3 and relativestrength4  and relativestrength5  then relativestrength1 else if relativestrength2 is less than relativestrength and relativestrength1 and relativestrength3 and relativestrength4  and relativestrength5 then relativestrength2 else if relativestrength3 is less than relativestrength and relativestrength1 and relativestrength2 and relativestrength4  and relativestrength5  then relativestrength3 else if relativestrength4 is less than relativestrength1 and relativestrength2 and relativestrength3 and relativestrength5 then relativestrength4 else relativestrength5,2);
#plot relstrength = relativestrengthu[21];

script SSF {

input price = close;
input cutoffLength = 10;

assert(cutoffLength > 0, "cutoffLength must be positive: " + cutoffLength);

def a1 = Exp(-Double.Pi * Sqrt(2) / cutoffLength);
def coeff2 = 2 * a1 * Cos(Sqrt(2) * Double.Pi / cutoffLength);
def coeff3 = - Sqr(a1);
def coeff1 = 1 - coeff2 - coeff3;
def filt = if IsNaN(price + price[1]) then filt[1] else coeff1 * (price + price[1]) / 2 + coeff2 * filt[1] + coeff3 * filt[2];

plot SuperSmootherFilter = if !IsNaN(price) then filt else Double.NaN;
}


input fast = 6;
input slow = 20;
input showbreakoutsignals = yes;

#plot avgfast = movavgexponential(relativestrengthu, fast);
def avgfast = SSF(relativestrengthu, fast);


#plot avgslow = movavgexponential(relativestrengthu, slow);
def avgslow = SSF(relativestrengthu, slow);



relativestrengthu.assignvaluecolor(if relativestrengthu>0 and avgfast>avgslow then color.green else if relativestrengthu>0 and avgfast<avgslow then color.dark_Green else if relativestrengthu<0 and avgfast<avgslow then color.dark_red else color.Red);
 

Similar threads

Top