public static HTInPhase Series(DataSeries ds) { string description = string.Concat(new object[] { "HTInPhase(", ds.Description, ")" }); if (ds.Cache.ContainsKey(description)) { return((HTInPhase)ds.Cache[description]); } HTInPhase _HTInPhase = new HTInPhase(ds, description); ds.Cache[description] = _HTInPhase; return(_HTInPhase); }
public HTPeriod(DataSeries ds, string description) : base(ds, description) { DataSeries InPhase = HTInPhase.Series(ds); DataSeries Quadrature = HTQuadrature.Series(ds); DataSeries Phase = new DataSeries(ds, "Phase"); DataSeries Period = new DataSeries(ds, "Period"); DataSeries InstPeriod = new DataSeries(ds, "InstPeriod"); DataSeries DeltaPhase = new DataSeries(ds, "DeltaPhase"); double Value = 0.0; DataSeries Result = new DataSeries(ds, "Result"); for (int bar = 7; bar < ds.Count; bar++) { // Compute the Period of the Dominant Cycle: //Use ArcTan to compute the current Phase if (Math.Abs(InPhase[bar] + InPhase[bar - 1]) > 0) { Phase[bar] = Math.Atan( Math.Abs((Quadrature[bar] + Quadrature[bar - 1]) / (InPhase[bar] + InPhase[bar - 1])) ) * 180 / Math.PI; // Where WL4 required degrees, .NET uses radians! } // Resolve the ArcTan ambiguity if ((InPhase[bar] < 0) & (Quadrature[bar] > 0)) { Phase[bar] = 180 - Phase[bar]; } if ((InPhase[bar] < 0) & (Quadrature[bar] < 0)) { Phase[bar] = 180 + Phase[bar]; } if ((InPhase[bar] > 0) & (Quadrature[bar] < 0)) { Phase[bar] = 360 - Phase[bar]; } //Compute A Differential Phase //Resolve phase wraparound, and limit delta phase errors DeltaPhase[bar] = Phase[bar - 1] - Phase[bar]; if ((Phase[bar - 1] < 90) & (Phase[bar] > 270)) { DeltaPhase[bar] = 360 + Phase[bar - 1] - Phase[bar]; } if (DeltaPhase[bar] < 1) { DeltaPhase[bar] = 1; } if (DeltaPhase[bar] > 60) { DeltaPhase[bar] = 60; } //Sum DeltaPhases to reach 360 degrees //The sum is the instantaneous period InstPeriod[bar] = 0; Value = 0; for (int Count = bar; Count >= 0; Count--) { Value += DeltaPhase[Count]; if ((Value > 360) & (InstPeriod[bar] == 0)) { InstPeriod[bar] = bar - Count; break; } } //Resolve Instantaneous Period errors and smooth if (InstPeriod[bar] == 0) { InstPeriod[bar] = InstPeriod[bar - 1]; } Period[bar] = 0.25 * InstPeriod[bar] + 0.75 * Period[bar - 1]; //Return the Hilbert Transform Period measured at the current bar: Result[bar] = Math.Truncate(Period[bar]); base[bar] = Result[bar]; } }