Is there any where I can find more information about how Wealth Lab 8 implemented the PhasorPeriod indicator? I found some source code on this page:
https://traders.com/Documentation/FEEDbk_docs/2022/11/TradersTips.html
But implementing these into Wealth Lab 8 has yielded different results than the WL8 version of PhasorPeriod, so I'm wondering what the discrepancy might be. I tried working with Claude/Gemini to figure it out, but they seem to be confused about how WL8 is calculating the PhasorAngle.
https://traders.com/Documentation/FEEDbk_docs/2022/11/TradersTips.html
But implementing these into Wealth Lab 8 has yielded different results than the WL8 version of PhasorPeriod, so I'm wondering what the discrepancy might be. I tried working with Claude/Gemini to figure it out, but they seem to be confused about how WL8 is calculating the PhasorAngle.
Rename
I'm confused on how this strategy knows when to Buy or Sell in the first place? The description alone (crossing above or below some TrendState) is not enough explanation. Show me the Buy and Sell rules using the cited indicators.
It doesn't seem like the WL version is very profitable in the given example. It doesn't appear the PhasorAngle indicator tracks the stock very well (for the WL implementation). The TradingView implementation seems to track phase between stock and Phasor indicator fairly well.
The equations wouldn't be nearly as messy if they employed complex numbers instead of real numbers for their calculations. Perhaps some of the trading apps can't handle complex numbers. Does anyone of a complex number version of this solution?
It doesn't seem like the WL version is very profitable in the given example. It doesn't appear the PhasorAngle indicator tracks the stock very well (for the WL implementation). The TradingView implementation seems to track phase between stock and Phasor indicator fairly well.
The equations wouldn't be nearly as messy if they employed complex numbers instead of real numbers for their calculations. Perhaps some of the trading apps can't handle complex numbers. Does anyone of a complex number version of this solution?
Here's the code for our PhasorAngle indicator, let me know if you come across anything.
CODE:
using WealthLab.Core; using WealthLab.Indicators; namespace WealthLab.TASC { public class PhasorAngle : IndicatorBase { public override string Name => "PhasorAngle"; public override string Abbreviation => "PhasorAngle"; public override string HelpDescription => "The Phasor Angle indicator by Dr. John Ehlers from S&C October 2022 issue."; public override string PaneTag => "PhasorAngle"; public override WLColor DefaultColor => WLColor.Red; //it's not a smoother public override bool IsSmoother => false; public PhasorAngle() { } public PhasorAngle(TimeSeries ds, int period = 28) { base.Parameters[0].Value = ds; base.Parameters[1].Value = period; this.Populate(); } //static method public static PhasorAngle Series(TimeSeries source, int period = 28) { string key = CacheKey("PhasorAngle", period); if (source.Cache.ContainsKey(key)) return (PhasorAngle)source.Cache[key]; PhasorAngle pa = new PhasorAngle(source, period); source.Cache[key] = pa; return pa; } protected override void GenerateParameters() { base.AddParameter("Source", ParameterType.TimeSeries, PriceComponent.Close); base.AddParameter("Lookback Period", ParameterType.Int32, 28); } public override void Populate() { TimeSeries ds = base.Parameters[0].AsTimeSeries; int period = base.Parameters[1].AsInt; this.DateTimes = ds.DateTimes; int FirstValidValue = period; if (ds.Count < FirstValidValue) { return; } TimeSeries Real = new TimeSeries(DateTimes); TimeSeries Imag = new TimeSeries(DateTimes); TimeSeries Angle = new TimeSeries(DateTimes); for (int idx = 0; idx < ds.Count; idx++) { Real[idx] = 0d; Imag[idx] = 0d; Angle[idx] = 0d; } for (int bar = 0; bar < ds.Count; bar++) { //Correlate with Cosine wave having a fixed period double Sx = 0, Sy = 0, Sxx = 0, Sxy = 0, Syy = 0; for (int count = 0; count < period; count++) { var X = (bar - count > 0) ? ds[bar - count - 1] : ds[0]; var Y = Math.Cos(360 * (count - 1) / period) * (180 / Math.PI); Sx += X; Sy += Y; Sxx += (X * X); Sxy += (X * Y); Syy += (Y * Y); } if ((((period * Sxx) - (Sx * Sx)) > 0) & (((period * Syy) - (Sy * Sy)) > 0)) { Real[bar] = (period * Sxy - Sx * Sy) / Math.Sqrt((period * Sxx - Sx * Sx) * (period * Syy - Sy * Sy)); } //Correlate with a Negative Sine wave having a fixed period Sx = 0; Sy = 0; Sxx = 0; Sxy = 0; Syy = 0; for (int count = 0; count < period; count++) { var X = (bar - count > 0) ? ds[bar - count - 1] : ds[0]; var Y = -Math.Sin(360 * (count - 1) / period) * (180 / Math.PI); Sx += X; Sy += Y; Sxx += (X * X); Sxy += (X * Y); Syy += (Y * Y); } if ((period * Sxx - Sx * Sx > 0) && (period * Syy - Sy * Sy > 0)) Imag[bar] = (period * Sxy - Sx * Sy) / Math.Sqrt((period * Sxx - Sx * Sx) * (period * Syy - Sy * Sy)); //Compute the angle as an arctangent function and resolve ambiguity if (Real[bar] != 0) Angle[bar] = 90 - Math.Atan(Imag[bar] / Real[bar]) * (180 / Math.PI); if (Real[bar] < 0) Angle[bar] = Angle[bar] - 180; //compensate for angle wraparound if (bar > 1) { if ((Math.Abs(Angle[bar - 1]) - Math.Abs(Angle[bar] - 360)) < (Angle[bar] - Angle[bar - 1]) && Angle[bar] > 90 && Angle[bar - 1] < -90) Angle[bar] = Angle[bar] - 360; //angle cannot go backwards if ((Angle[bar] < Angle[bar - 1]) && ((Angle[bar] > -135 && Angle[bar - 1] < 135) || (Angle[bar] < -90 && Angle[bar - 1] < -90))) Angle[bar] = Angle[bar - 1]; } base.Values[bar] = Angle[bar]; } PrefillNan(period); } } }
I think it would be best to reference the original paper for this, which I don't have. Perhaps someone with the original paper can check it over. Unfortunately, if the original paper isn't employing complex numbers (Is it in real numbers?), then it will be harder to follow.
I wonder if AI could convert the solution to complex numbers (and in terms of pi instead of degrees) so it's easier to follow?
I wonder if AI could convert the solution to complex numbers (and in terms of pi instead of degrees) so it's easier to follow?
CODE:
var Y = Math.Cos(360 * (count - 1) / period) * (180 / Math.PI);
The input to Math.Cos(...) should be radians, shouldn't it?
QUOTE:
The input to Math.Cos(...) should be radians, shouldn't it?
Correct. I think they are trying to convert Count to degrees and then into radians with the pi factor.
I'm not sure why there's a (count - 1) in
CODE:because that's going to force the angle to go negative when count=0. Why would you want that? But I won't suggest a change without reading the original article (which I don't have).
Math.Cos(360 * (count - 1) ...
It would have been easier to follow if Count was in terms of radians in the first place. That would have been the way I would have done it. They made this way too complicated. And it's perfectly normal to plot phase in terms of pi, not degrees (so 1.0 phase would be 1*pi radians). You could convert phase lag to time delay if you factored in sampling rate (scale), but that might confuse people.
Splitting the real and imaginary parts of the complex numbers up really made it confusing. One would never publish this that way in an engineering journal. I think the problem is some trading apps can't handle complex arithmetic, so John Ehlers broke the complex equations up into component parts (which doubles the number of equations and makes them totally unfamiliar to engineers). :(
Ehlers' books use complex numbers as you would expect, so there's half the number of equations and it's much easier to follow. I'm "guessing" the original article has an introduction using complex math, so it's easier to follow conceptually.
Indeed it should, does calling DegToRad make the indicator provide more expected results?
QUOTE:
Indeed it should,
As I said in Post #5, just put count in terms of radians and you solve your problem. And you'll get rid of that stupid (count-1) that creates a negative angle for count=0.
CODE:But I'm not going to recommend code changes until I read Ehlers' article (which I don't have).
for (double count=0.0; count < 2.0*Math.PI; count += 2.0*Math.PI/period) double Y = Math.Cos(count);
What I will say is that the results for the TradingView version looks reasonable to me, so if you just copy their code you'll probably be alright.
Your Response
Post
Edit Post
Login is required