Syntax
public InverseFisherRSI(WealthLab.DataSeries ds, int rsiPeriod, int emaPeriod, string description)
public static InverseFisherRSI Series(WealthLab.DataSeries ds, int rsiPeriod, int emaPeriod)
Parameter Description
ds |
DataSeries for the InverseFisherRSI calculation |
rsiPeriod |
The RSI period used in the InverseFisherRSI calculation. |
smoothPeriod |
The EMA period used in the InverseFisherRSI calculation. |
Description
InverseFisherRSI by Sylvain Vervoot from the October 2010 issue of
Stocks & Commodities magazine. Like RSI, InverseFisherRSI is a momentum oscillator with values between 0 and 100. It provides clear buy and sell signals as the indicator crosses the 50 level. The author suggests combining InverseFisherRSI with
ARSI to find short-term reversal points based on divergences (see Example) and/or with a medium-term stochastic oscillator to track the medium-term price moves.
Calculation
See open source, which formalizes the indicator calculation shown in the
October 2010 TASC example's
SVEInvFisherRSI DataSeries function.
Example
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
using TASCIndicators;
namespace WealthLab.Strategies
{
public class ShortDivergence : WealthScript
{
StrategyParameter _rsiPeriod;
StrategyParameter _emaPeriod;
StrategyParameter _arsiPeriod;
public ShortDivergence()
{
_arsiPeriod = CreateParameter("ARSI_Period", 10, 2, 200, 20);
_rsiPeriod = CreateParameter("RSI Period", 4, 2, 30, 1);
_emaPeriod = CreateParameter("EMA Period", 4, 2, 10, 1);
}
protected override void Execute()
{
HideVolume();
const double d = 1.01;
int perRSI = _rsiPeriod.ValueInt;
int perEMA = _emaPeriod.ValueInt;
/* Create and plot indicators */
DataSeries arsi = ARSI.Series(Close, _arsiPeriod.ValueInt);
ChartPane rsiPane = CreatePane(40, true, true);
PlotSeries(rsiPane, arsi, Color.Red, LineStyle.Solid, 2);
DataSeries invfish = InverseFisherRSI.Series(Close, perRSI, perEMA);
ChartPane cp = CreatePane(40, true, true);
PlotSeries(cp, invfish, Color.Navy, LineStyle.Solid, 2);
/* Trading loop */
for (int bar = 3 * GetTradingLoopStartBar(4) ; bar < Bars.Count; bar++)
{
if (IsLastPositionActive)
{
Position p = LastPosition;
if (bar + 1 - p.EntryBar > 6)
ExitAtMarket(bar + 1, p, "Time-based");
}
else if (CrossUnder(bar, invfish, 70))
{
// check the last two arsi peaks for negative divergence with price
int pb1 = (int)PeakBar.Value(bar, arsi, 20, PeakTroughMode.Value);
if (pb1 == -1) continue;
int pb2 = (int)PeakBar.Value(pb1, arsi, 20, PeakTroughMode.Value);
if (pb2 == -1) continue;
if ( Math.Sign(arsipb1 - arsipb2) == -1 && Math.Sign(Highpb1 - Highpb2) == 1)
{
SetBackgroundColor(bar, Color.FromArgb(50, Color.Green));
DrawLine(rsiPane, pb2, arsipb2, pb1, arsipb1, Color.Blue, LineStyle.Solid, 2);
DrawLine(PricePane, pb2, Highpb2 * d, pb1, Highpb1 * d, Color.Blue, LineStyle.Solid, 2);
ShortAtMarket(bar + 1);
}
}
}
}
}
}