16 using System.Diagnostics;
28 private readonly
int _length;
29 private readonly IndicatorBase<IndicatorDataPoint> _input;
30 private readonly IndicatorBase<IndicatorDataPoint> _prev;
31 private readonly IndicatorBase<IndicatorDataPoint> _detrendPrice;
32 private readonly IndicatorBase<IndicatorDataPoint> _detrendPriceDelay2;
33 private readonly IndicatorBase<IndicatorDataPoint> _detrendPriceDelay4;
34 private readonly IndicatorBase<IndicatorDataPoint> _inPhaseDelay3;
35 private readonly IndicatorBase<IndicatorDataPoint> _quadratureDelay2;
40 public IndicatorBase<IndicatorDataPoint>
InPhase {
get; }
45 public IndicatorBase<IndicatorDataPoint>
Quadrature {
get; }
67 public HilbertTransform(
string name,
int length, decimal inPhaseMultiplicationFactor, decimal quadratureMultiplicationFactor)
72 _input =
new Identity(name +
"_input");
73 _prev =
new Delay(name +
"_prev", length);
74 _detrendPrice = _input.Minus(_prev);
76 _detrendPriceDelay2 =
new Delay(name +
"_detrendPriceDelay2", 1);
77 _detrendPriceDelay4 =
new Delay(name +
"_detrendPriceDelay4", 3);
79 _inPhaseDelay3 =
new Delay(name +
"_inPhaseDelay3", 2);
80 _quadratureDelay2 =
new Delay(name +
"_quadratureDelay2", 1);
82 InPhase =
new FunctionalIndicator<IndicatorDataPoint>(name +
"_inPhase",
90 var v2Value = _detrendPriceDelay2.IsReady ? _detrendPriceDelay2.Current.Value : 0m;
91 var v4Value = _detrendPriceDelay4.IsReady ? _detrendPriceDelay4.Current.Value : 0m;
92 var inPhase3Value = _inPhaseDelay3.IsReady ? _inPhaseDelay3.Current.Value : 0m;
93 return 1.25m * (v4Value - v2Value * inPhaseMultiplicationFactor) + inPhase3Value * inPhaseMultiplicationFactor;
95 _ => Samples > length + 2,
98 _detrendPrice.Reset();
99 _detrendPriceDelay2.Reset();
100 _detrendPriceDelay4.Reset();
101 _inPhaseDelay3.Reset();
104 Quadrature =
new FunctionalIndicator<IndicatorDataPoint>(name +
"_quad",
112 var v2Value = _detrendPriceDelay2.IsReady ? _detrendPriceDelay2.Current.Value : 0m;
113 var v1Value = _detrendPrice.IsReady ? _detrendPrice.Current.Value : 0m;
114 var quadrature2Value = _quadratureDelay2.IsReady ? _quadratureDelay2.Current.Value : 0m;
115 return v2Value - v1Value * quadratureMultiplicationFactor + quadrature2Value * quadratureMultiplicationFactor;
117 _ => Samples > length,
120 _detrendPrice.Reset();
121 _detrendPriceDelay2.Reset();
122 _quadratureDelay2.Reset();
137 public HilbertTransform(
int length = 7, decimal inPhaseMultiplicationFactor = 0.635m, decimal quadratureMultiplicationFactor = 0.338m)
138 : this($
"Hilbert({length}, {inPhaseMultiplicationFactor}, {quadratureMultiplicationFactor})", length, inPhaseMultiplicationFactor, quadratureMultiplicationFactor)
149 Debug.Assert(input !=
null, nameof(input) +
" != null");
151 _input.Update(input);
156 _detrendPrice.Update(input);
159 if (_detrendPrice.IsReady)
161 _detrendPriceDelay2.Update(_detrendPrice.Current);
162 _detrendPriceDelay4.Update(_detrendPrice.Current);
168 _inPhaseDelay3.Update(
InPhase.Current);
189 _detrendPrice.Reset();
190 _detrendPriceDelay2.Reset();
191 _detrendPriceDelay4.Reset();
192 _inPhaseDelay3.Reset();
193 _quadratureDelay2.Reset();