Conversion of Ehlers' "DominantCycle" from TradeStation

Viewing 11 posts - 1 through 11 (of 11 total)
  • Author
    Posts
  • #107929 quote
    Ξ3
    Participant
    Average
    Hi Nicolas, Moderators & Advanced Users,
    I am really hoping that someone can come up with a clever way of converting the below John Ehlers indicator found in the September 2016 TASC magazine to PRT code. Despite my best efforts I have not come up with a way to achieve this and believe me I have tried.
    Basically it calculates the dominant cycle period value using the “autocorrelation periodogram” method, which Ehlers recommends. All details I have on this indicator can be found here: http://traders.com/Documentation/FEEDbk_docs/2016/09/TradersTips.html
    I know that PRT does not support arrays but I have overcome this problem by defining multiple variables to “simulate” / “cater for”  an array maximum of 60 (even 48 will do). I have also tried to remove as many loops as possible but haven’t managed to overcome the infinite loop / too many iterations problem. Any ideas or help will be greatly appreciated?
    An extract of the TradeStation code that I am desperate to convert to ProRealTime is below:
    Many thanks and praise to anyone willing to take on this challenge 😉
    ———————————————————————————-
    inputs:
    EnhanceResolution( false ) ;
    variables:
    AvgLength( 3 ), M( 0 ), N( 0 ), X( 0 ),
    Y( 0 ), alpha1( 0 ), HP( 0 ), a1( 0 ),b1( 0 ),
    c1( 0 ), c2( 0 ), c3( 0 ), Filt( 0 ), Lag( 0 ),
    count( 0 ), Sx( 0 ), Sy( 0 ), Sxx( 0 ),
    Syy( 0 ), Sxy( 0 ), Period( 0 ), Sp( 0 ),
    Spx( 0 ), MaxPwr( 0 ), PeakPwr( 0 ),
    DominantCycle( 0 ) ;
    arrays: Corr[70]( 0 ), CosinePart[70]( 0 ),
    SinePart[70]( 0 ),SqSum[70]( 0 ),
    R[70, 2]( 0 ), Pwr[70]( 0 ) ;
    //Highpass Filter and SuperSmoother
    //Filter together form a Roofing Filter
    //Highpass Filter
    alpha1 = ( 1 – Sine ( 360 / 48 ) )
    / Cosine( 360 / 48 ) ;
    HP = .5 * ( 1 + alpha1 )
    * ( Close – Close[1] ) + alpha1 * HP[1] ;
    //Smooth with a SuperSmoother Filter
    a1 = ExpValue( -1.414 * 3.14159 / 8 ) ;
    b1 = 2 * a1 * Cosine( 1.414 * 180 / 8 ) ;
    c2 = b1 ;
    c3 = -a1 * a1 ;
    c1 = 1 – c2 – c3 ;
    Filt = c1 * ( HP + HP[1] ) / 2
    + c2 * Filt[1] + c3 * Filt[2] ;
    //Pearson correlation for each value of lag
    for Lag = 0 to 48
    begin
    //Set the averaging length as M
    M = AvgLength ;
    If AvgLength = 0 then
    M = Lag ;
    Sx = 0 ;
    Sy = 0 ;
    Sxx = 0 ;
    Syy = 0 ;
    Sxy = 0 ;
    for count = 0 to M – 1
    begin
    X = Filt[count] ;
    Y = Filt[Lag + count] ;
    Sx = Sx + X ;
    Sy = Sy + Y ;
    Sxx = Sxx + X * X ;
    Sxy = Sxy + X * Y ;
    Syy = Syy + Y * Y ;
    end ;
    if ( M * Sxx – Sx * Sx ) * ( M * Syy – Sy * Sy ) > 0 then
    Corr[Lag] = ( M * Sxy – Sx * Sy )
    / SquareRoot( ( M * Sxx – Sx * Sx )
    * ( M * Syy – Sy * Sy ) ) ;
    end ;
    //Compute the Fourier Transform for each Correlation
    for Period = 8 to 48
    begin
    CosinePart[Period] = 0;
    SinePart[Period] = 0;
    For N = 3 to 48
    Begin
    CosinePart[Period] = CosinePart[Period] +
    Corr[N]*Cosine(360*N / Period);
    SinePart[Period] = SinePart[Period]
    + Corr[N]*Sine(360*N / Period);
    End;
    SqSum[Period] = CosinePart[Period]*CosinePart[Period]
    + SinePart[Period]*SinePart[Period];
    End ;
    For Period = 8 to 48
    Begin
    R[Period, 2] = R[Period, 1];
    R[Period, 1] = .2*SqSum[Period]*SqSum[Period]
    + .8*R[Period,2];
    End;
    //Find Maximum Power Level for Normalization
    MaxPwr = 0;
    For Period = 8 to 48
    begin
    If R[Period, 1] > MaxPwr then
    MaxPwr = R[Period, 1];
    End;
    For Period = 8 to 48
    Begin
    Pwr[Period] = R[Period, 1] / MaxPwr;
    End;
    //Optionally increase Display Resolution
    //by raising the NormPwr to a higher
    //mathematically power (since the maximum
    //amplitude is unity, cubing all
    //amplitudes further reduces the smaller ones).
    If EnhanceResolution = True then
    Begin
    For Period = 8 to 48
    Begin
    Pwr[Period] = Power(Pwr[Period], 3);
    End;
    End;
    //Compute the dominant cycle using
    //the CG of the spectrum
    DominantCycle = 0;
    PeakPwr = 0;
    For Period = 8 to 48
    Begin
    If Pwr[Period] > PeakPwr then
    PeakPwr = Pwr[Period];
    End;
    Spx = 0;
    Sp = 0;
    For Period = 8 to 48
    Begin
    If PeakPwr >= .25 and Pwr[Period] >= .25 then
    Begin
    Spx = Spx + Period*Pwr[Period];
    Sp = Sp + Pwr[Period];
    End;
    End;
    If Sp <> 0 then
    DominantCycle = Spx / Sp;
    If Sp < .25 then
    DominantCycle = DominantCycle[1];
    if DominantCycle < 1 then DominantCycle = 1 ;
    Print( Bardatetime.ToString(), ” | “, Ceiling( DominantCycle ) ) ;

     

    #107930 quote
    robertogozzi
    Moderator
    Master

    >> For clarity of messages on ProRealCode’s forums, please use the “insert code PRT” button to separate the text of the code part! Thank you! <<

    Ξ3 thanked this post
    #107932 quote
    Ξ3
    Participant
    Average

    Never even saw that button before you pointed it out now, sorry. 🙁

    Will sure to use it in future, thanks! 🙂

    #107942 quote
    Nicolas
    Keymaster
    Master

    Right, without arrays, the solution is to use loop and nested loops.. but we quickly fell in the in infinite loop ambush!

    There was a try about dominant cycle indicator conversion in this thread: https://www.prorealcode.com/topic/calcul-de-la-periode-des-cycles-selon-ehlers/

    Or even in this one: https://www.prorealcode.com/topic/ehlers-sinewave-indicator/

    #107949 quote
    Ξ3
    Participant
    Average

    Bonjour Nicolas,

    I did see the English post on this but I somehow missed the French one (although I do understand a bit of French) and I have now gone through it as well. Both of these posts seem to be making use of the “homodyne discriminator” method. FYI, there is a link to a working copy of this method in another post on ProRealCode which comes from the HK Lisse Blog for those that are interested http://hk-lisse.over-blog.com/tag/les%20cycles/

    The code above however is from Ehlers’ more recent work and his “new preferred” method for calculating the dominant cycle period, which I have been trying to get working in PRT.

    Below is my most recent code attempt to emulate the “new” logic taking into account the ProRealTime restrictions of arrays and loop limitations but I have not progressed past a certain point and need some fresh eyes on solving the problem (you have been very resourceful in the past ;-)) The code runs perfectly in ProRealTime up to the point where it calculates the “Maximum Power Level For Normalization” (I wanted to give you the line number but it doesn’t show when editing this post – roughly line 765 which contains ”   If 1=2 then // 1=2″). Currently my code is halted at this point (to debug it) but the problem is highlighted if you simply comment out or remove all lines that contain the string “1=2”. Any ideas to get the full code to execute in PRT to calculate the correct “AutoPeriodRaw” value?

    Merci beaucoup!

    #107966 quote
    Nicolas
    Keymaster
    Master

    Thanks, could you please repost the code as an attached file (itf or even a text file), because the code is too long for the forum! 🙂

    #108031 quote
    Ξ3
    Participant
    Average

    Sorry about that. I hope I didn’t break anything?

    I attach a text file of my code 😉

    #115249 quote
    avangers
    Participant
    New

    Hi, newbie here and in coding.
    I don’t understand how the left hand side of the equation can be solved if the right hand side has the same variable. like the ” cosinepart[period]” is on both sides. They wont be cancelled out?
    I don’t want to blindly copy codes and done.

    CosinePart[Period] = CosinePart[Period] +
    Corr[N]*Cosine(360*N / Period);

    Hope to get a response from the experts

    #115281 quote
    Ξ3
    Participant
    Average

    Hi Avangers,

    The way that coding works allows for this. Effectively you can modify an existing value, using its “current” value state.

    A simpler example of this would be:

    aVariable = 20

    aVariable = aVariable + 1

    After the above two lines of code, aVariable will now be 21

    Hope this helps?

    #179890 quote
    sal157011
    Participant
    Junior

    Now that the arrays are available in prorealtime would it be possible for you to rewrite the https://www.prorealcode.com/wp-content/uploads/2019/09/IndCyclePeriodogram.v0.1.txt code with the arrays? Thank you.

    #193463 quote
    Ξ3
    Participant
    Average

    Hi sal157011,

    Apologies for only responding now…

    As I have not been able to code this, I have moved on to other indicators that do not make use of arrays.

    If you or anyone else have been able to code this in ProRealTime, please do post it here for all to benefit from it…

Viewing 11 posts - 1 through 11 (of 11 total)
  • You must be logged in to reply to this topic.

Conversion of Ehlers' "DominantCycle" from TradeStation


ProBuilder: Indicators & Custom Tools

New Reply
Author
author-avatar
Ξ3 @cbeukes Participant
Summary

This topic contains 10 replies,
has 2 voices, and was last updated by Ξ3
3 years, 8 months ago.

Topic Details
Forum: ProBuilder: Indicators & Custom Tools
Language: English
Started: 09/19/2019
Status: Active
Attachments: 1 files
Logo Logo
Loading...