Log in to see Cloud of Tags

Wealth-Lab Wiki

TASC 2020-08 | Tracking Relative Strength In Four Dimensions (RS4r) (Garofallou)

RSS

Traders' Tip text

In this month's Tip space we show how to screen for symbols that meet a specified criteria as of the most recent date. The criteria here is the value of an oscillator like RS4 or RS5: the strongest ranked funds get the preference.

To set things up, first have your index funds (or whatever instruments required) in a Wealth-Lab DataSet and update their data. Then in the screener code, type in your symbol names instead of author's choice of funds:

{"FXAIX", "FNCMX", "FSMDX", "FSSNX", "FSPGX", "FLCOX", "FPADX", "FSRNX", "FSAGX", "FSUTX", "FTBFX"};
By running the screener below on a DataSet of chosen symbols in portfolio backtest mode, you'll get a list of signals to buy on the open in the Alerts view as on Figure 1:


Image

Figure 1. A view of the Alerts tab with 2 signals with the highest reading of the RS5 oscillator.


If you wish to visualize the oscillators, double click on any trading signal. Wealth-Lab will plot them on a chart like Figure 2 illustrates:


Image

Figure 2. A sample plot of the RS4 and RS5 oscillators built using author’s default set of 11 index funds on the daily chart of QQQ. Index fund data provided by Tiingo.


On a closing note, simply download public strategies from Wealth-Lab (hit Ctrl-O and choose "Download...") to get the trading system code below:

WealthScript Code (C#)

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;

namespace WealthLab.Strategies { public class TASC2020_09 : WealthScript { LineStyle ls = LineStyle.Solid; public DataSeries RS2t(DataSeries ds, string index, int period = 10, bool plotSeries = false) { var rs = new DataSeries(ds, string.Format("RS2t({0},{1},{2}", ds.Description, index, period)); var extSym = GetExternalSymbol(index, true); var RS1 = ds / extSym.Close;

var Fast = EMAModern.Series(RS1, period); //Fast MA: Orange var Med = SMA.Series(Fast, 7); //Medium MA: Green var Slow = SMA.Series(Fast, 15); //Slow MA: Red var Vslow = SMA.Series(Slow, 30); //V Slow MA: Blue

int Tier1 = 0, Tier2 = 0, Tier3 = 0, Tier4 = 0;

for (int bar = GetTradingLoopStartBar(Math.Max(period * 3, 30)); bar < ds.Count; bar++) { Tier1 = (Fast[bar] >= Med[bar] && Med[bar] >= Slow[bar] && Slow[bar] >= Vslow[bar]) ? 10 : 0; Tier2 = (Fast[bar] >= Med[bar] && Med[bar] >= Slow[bar] && Slow[bar] < Vslow[bar]) ? 9 : 0; Tier3 = (Fast[bar] < Med[bar] && Med[bar] >= Slow[bar] && Slow[bar] >= Vslow[bar]) ? 9 : 0; Tier4 = (Fast[bar] < Med[bar] && Med[bar] >= Slow[bar] && Slow[bar] < Vslow[bar]) ? 5 : 0;

rs[bar] = Tier1 + Tier2 + Tier3 + Tier4; }

if (plotSeries) { var rp = CreatePane(50, false, true); PlotSeries(rp, RS1, Color.Black, ls, 1); PlotSeries(rp, Fast, Color.DarkOrange, ls, 2); PlotSeries(rp, Med, Color.MediumSeaGreen, ls, 2); PlotSeries(rp, Slow, Color.Crimson, ls, 2); PlotSeries(rp, Vslow, Color.SteelBlue, ls, 2); }

return rs; }

protected override void Execute() { int period = 10; var lstIndices = new List<string>() { "FXAIX", "FNCMX", "FSMDX", "FSSNX", "FSPGX", "FLCOX", "FPADX", "FSRNX", "FSAGX", "FSUTX", "FTBFX"};

var RS3x = Close * 0; foreach (var fund in lstIndices) { RS3x += RS2t(Close, fund, period); }

var RS4 = (RS3x / lstIndices.Count) * 10; //Scaled to 0 to 100 for (int bar = 0; bar < RS4.Count; bar++) RS4[bar] = Math.Round(RS4[bar]); var RS4osc = SMA.Series(RS4, 3); //RS oscillator var Mv = SMA.Series(RS4osc, 5); //RSosc's signal line

var rp = CreatePane(40, false, true); PlotSeries(rp, RS4osc, Color.DarkSlateBlue, ls, 2, "RS4r Oscillator"); PlotSeries(rp, Mv, Color.Crimson, ls, 2, "SMA5"); HideVolume();

DrawHorzLine(rp, 80, Color.Red, LineStyle.Dashed, 1); DrawHorzLine(rp, 100, Color.Black, LineStyle.Dashed, 1);

var mvRS4 = WMA.Series(RS4, 4); //Moving Avg of RS4r var R5 = new DataSeries(Close, string.Format("R5({0})",period)); var x = Open * 0; for (int bar = 1; bar < RS4.Count; bar++) { bool RS4up = (RS4[bar] >= 80 || RS4[bar] > mvRS4[bar]); //RS4r is above signal line x[bar] = RS4[bar] >= 80 ? 1 : 0; //RS4r must be >= 80 }

//Avg of >80 scores in period for (int bar = 1; bar < RS4.Count; bar++) R5[bar] = (Sum.Series(x, period)[bar] / period) * 100;

var rp5 = CreatePane(20, false, true); PlotSeries(rp5, R5, Color.Red, ls, 2, "R5");

int b = Bars.Count - 1; if (b < Math.Max(period * 3, 30)) return; //if ( RS4osc[b] > 80 ) BuyAtMarket(b + 1, Math.Round(RS4osc[b]).ToString()); if ( R5[b] > 80 ) BuyAtMarket(b + 1, Math.Round(R5[b]).ToString()); } } }

Gene Geren (Eugene)
Wealth-Lab team

Important Disclaimer: The information provided by Wealth-Lab is strictly for informational purposes and is not to be construed as advice or solicitation to buy or sell any security.  The owner of Wealth-Lab.com assumes no liability resulting from the use of the material contained herein for investment purposes. By using this web site, you agree to the terms of this disclaimer and our Terms of Use.


ScrewTurn Wiki. Some of the icons created by FamFamFam.