如何正确计算 Fisher 变换指标
How to correctly calculate Fisher Transform indicator
我正在编写一个小型技术分析库,其中包含 TA-lib 中不可用的项目。我从在 cTrader 上找到的示例开始,并将其与 TradingView 版本中的代码进行匹配。
这是来自 TradingView 的 Pine Script 代码:
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]
这是我尝试实现指标:
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
问题
输出值似乎在预期范围内,但是我的 Fisher 变换交叉 不 与我在 TradingView 版本的指标上看到的相匹配。
问题
如何在 C# 中正确实施 Fisher 变换指标?我希望这与 TradingView 的 Fisher 变换输出相匹配。
我所知道的
我已经根据我个人编写的其他指标和来自 TA-Lib 的指标检查了我的数据,这些指标通过了我的单元测试。我还逐个蜡烛检查了我的数据与 TradingView 数据蜡烛,发现我的数据符合预期。所以我不怀疑我的数据是问题。
细节
下图是应用于 TradingView 图表的上图 Fisher 转换代码。我的目标是尽可能匹配此输出。
费舍尔 青色
触发器 洋红色
预期产出:
交叉完成于 15:30 ET
Fisher 近似值为 2.86
大约触发值为 1.79
交叉完成于 10:45 ET
Fisher 近似值为 -3.67
大约触发值是-3.10
我的实际输出:
交叉完成于 15:30 ET
我的 Fisher 值是 1.64
我的触发值是1.99
交叉完成于 10:45 ET
我的 Fisher 值为 -1.63
我的触发值是-2.00
赏金
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 (5/14 更新)
帮助我的 FisherTransform 测试通过,我会奖励赏金。
如果您需要任何其他资源或信息,请发表评论。
我会考虑的备选答案
在 C# 中提交您自己的工作 FisherTransform
解释为什么我的 FisherTransform 实际上按预期工作
代码有两个错误。
1) 错误的额外括号。正确的行是:
_value1 = Maths.Normalize(0.66m * (Maths.Divide(Series.Average[index] - _minLow, Math.Max(_maxHigh - _minLow, 0.001m)) - 0.5m) + 0.67m * _lastValue1);
2) 最小和最大函数必须是:
public static decimal Highest(this decimal[] series, int length, int index)
{
var maxVal = series[index]; // <----- HERE WAS AN ERROR!
var lookback = Math.Max(index - length, 0);
for (int i = index; i-- > lookback;)
maxVal = Math.Max(series[i], maxVal);
return maxVal;
}
public static decimal Lowest(this decimal[] series, int length, int index)
{
var minVal = series[index]; // <----- HERE WAS AN ERROR!
var lookback = Math.Max(index - length, 0);
for (int i = index; i-- > lookback;)
{
//if (series[i] != 0) // <----- HERE WAS AN ERROR!
minVal = Math.Min(series[i], minVal);
}
return minVal;
}
3) 令人困惑的测试参数。请重新检查您的单元测试值。更新测试后仍未修复。例如,第一个 FisherTransforms_ValuesAreReasonablyClose_First()
具有混合值
var fish = result.Fish.Last(); //is equal to -3.1113144510775780365063063706
var trig = result.Trigger.Last(); //is equal to -3.6057793808025449204415435710
// TradingView Values for NFLX 5m chart at 10:45 ET
var fisherValue = -3.67m;
var triggerValue = -3.10m;
我正在编写一个小型技术分析库,其中包含 TA-lib 中不可用的项目。我从在 cTrader 上找到的示例开始,并将其与 TradingView 版本中的代码进行匹配。
这是来自 TradingView 的 Pine Script 代码:
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]
这是我尝试实现指标:
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
问题
输出值似乎在预期范围内,但是我的 Fisher 变换交叉 不 与我在 TradingView 版本的指标上看到的相匹配。
问题
如何在 C# 中正确实施 Fisher 变换指标?我希望这与 TradingView 的 Fisher 变换输出相匹配。
我所知道的
我已经根据我个人编写的其他指标和来自 TA-Lib 的指标检查了我的数据,这些指标通过了我的单元测试。我还逐个蜡烛检查了我的数据与 TradingView 数据蜡烛,发现我的数据符合预期。所以我不怀疑我的数据是问题。
细节
下图是应用于 TradingView 图表的上图 Fisher 转换代码。我的目标是尽可能匹配此输出。
费舍尔 青色 触发器 洋红色
预期产出:
交叉完成于 15:30 ET
Fisher 近似值为 2.86
大约触发值为 1.79
交叉完成于 10:45 ET
Fisher 近似值为 -3.67
大约触发值是-3.10
我的实际输出:
交叉完成于 15:30 ET
我的 Fisher 值是 1.64
我的触发值是1.99
交叉完成于 10:45 ET
我的 Fisher 值为 -1.63
我的触发值是-2.00
赏金
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 (5/14 更新)
帮助我的 FisherTransform 测试通过,我会奖励赏金。
如果您需要任何其他资源或信息,请发表评论。
我会考虑的备选答案
在 C# 中提交您自己的工作 FisherTransform
解释为什么我的 FisherTransform 实际上按预期工作
代码有两个错误。
1) 错误的额外括号。正确的行是:
_value1 = Maths.Normalize(0.66m * (Maths.Divide(Series.Average[index] - _minLow, Math.Max(_maxHigh - _minLow, 0.001m)) - 0.5m) + 0.67m * _lastValue1);
2) 最小和最大函数必须是:
public static decimal Highest(this decimal[] series, int length, int index)
{
var maxVal = series[index]; // <----- HERE WAS AN ERROR!
var lookback = Math.Max(index - length, 0);
for (int i = index; i-- > lookback;)
maxVal = Math.Max(series[i], maxVal);
return maxVal;
}
public static decimal Lowest(this decimal[] series, int length, int index)
{
var minVal = series[index]; // <----- HERE WAS AN ERROR!
var lookback = Math.Max(index - length, 0);
for (int i = index; i-- > lookback;)
{
//if (series[i] != 0) // <----- HERE WAS AN ERROR!
minVal = Math.Min(series[i], minVal);
}
return minVal;
}
3) 令人困惑的测试参数。请重新检查您的单元测试值。更新测试后仍未修复。例如,第一个 FisherTransforms_ValuesAreReasonablyClose_First()
具有混合值
var fish = result.Fish.Last(); //is equal to -3.1113144510775780365063063706
var trig = result.Trigger.Last(); //is equal to -3.6057793808025449204415435710
// TradingView Values for NFLX 5m chart at 10:45 ET
var fisherValue = -3.67m;
var triggerValue = -3.10m;