I'm writing a small technical analysis library that consists of items that are not availabile in TA-lib. I've started with an example I found on cTrader and matched it against the code found in the TradingView version.
Here's the Pine Script code from TradingView:
len = input(9, minval=1, title="Length")
high_ = highest(hl2, len)
low_ = lowest(hl2, len)
round_(val) => val > .99 ? .999 : val < -.99 ? -.999 : val
value = 0.0
value := round_(.66 * ((hl2 - low_) / max(high_ - low_, .001) - .5) + .67 * nz(value[1]))
fish1 = 0.0
fish1 := .5 * log((1 + value) / max(1 - value, .001)) + .5 * nz(fish1[1])
fish2 = fish1[1]
Here's my attempt to implement the indicator:
public class FisherTransform : IndicatorBase
{
public int Length = 9;
public decimal[] Fish { get; set; }
public decimal[] Trigger { get; set; }
decimal _maxHigh;
decimal _minLow;
private decimal _value1;
private decimal _lastValue1;
public FisherTransform(IEnumerable<Candle> candles, int length)
: base(candles)
{
Length = length;
RequiredCount = Length;
_lastValue1 = 1;
}
protected override void Initialize()
{
Fish = new decimal[Series.Length];
Trigger = new decimal[Series.Length];
}
public override void Compute(int startIndex = 0, int? endIndex = null)
{
if (endIndex == null)
endIndex = Series.Length;
for (int index = 0; index < endIndex; index++)
{
if (index == 1)
{
Fish[index - 1] = 1;
}
_minLow = Series.Average.Lowest(Length, index);
_maxHigh = Series.Average.Highest(Length, index);
_value1 = Maths.Normalize(0.66m * ((Maths.Divide(Series.Average[index] - _minLow, Math.Max(_maxHigh - _minLow, 0.001m)) - 0.5m) + 0.67m * _lastValue1));
_lastValue1 = _value1;
Fish[index] = 0.5m * Maths.Log(Maths.Divide(1 + _value1, Math.Max(1 - _value1, .001m))) + 0.5m * Fish[index - 1];
Trigger[index] = Fish[index - 1];
}
}
}
IndicatorBase class and CandleSeries class
The problem
The output values appear to be within the expected range however my Fisher Transform cross-overs do not match up with what I am seeing on TradingView's version of the indicator.
Question
How do I properly implement the Fisher Transform indicator in C#? I'd like this to match TradingView's Fisher Transform output.
What I Know
I've check my data against other indicators that I have personally written and indicators from TA-Lib and those indicators pass my unit tests. I've also checked my data against the TradingView data candle by candle and found that my data matches as expected. So I don't suspect my data is the issue.
Specifics
Pictured below is the above-shown Fisher Transform code applied to a TradingView chart. My goal is to match this output as close as possible.
Fisher Cyan Trigger Magenta
Expected Outputs:
Crossover completed at 15:30 ET
Approx Fisher Value is 2.86
Approx Trigger Value is 1.79
Crossover completed at 10:45 ET
Approx Fisher Value is -3.67
Approx Trigger Value is -3.10
My Actual Outputs:
Crossover completed at 15:30 ET
My Fisher Value is 1.64
My Trigger Value is 1.99
Crossover completed at 10:45 ET
My Fisher Value is -1.63
My Trigger Value is -2.00
Bounty
To make your life easier I'm including a small console application complete with passing and failing unit tests. All unit tests are conducted against the same data set. The passing unit tests are from a tested working Simple Moving Average indicator. The failing unit tests are against the Fisher Transform indicator in question.
Project Files (updated 5/14)
Help get my FisherTransform tests to pass and I'll award the bounty.
Just comment if you need any additional resources or information.
Alternative Answers that I'll consider
Submit your own working FisherTransform in C#
Explain why my FisherTransform is actually working as expected