Cybernetic Oscillator by John F. Ehlers

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #251959 quote
    elekin.
    Participant
    New

    Hello guys,

    I’ve coded the cybernetic oscillator by John F. Ehlers, taking it from the article “Making a Better Oscillator” from the TASC journal, but I’ve faced some issues.

    The original code is written in Easy Language, you can find it in the pdf attached. I wrote in the same page the code of the high-pass filter, the Super Smoother and the RMS formula to obtain the final formula of the cybernetic oscillator, without calling the other indicators from external codes.

    The problem is that the oscillator’s values exploded in the first periods while are too small in the latests, so it seems like it’s not normalized as it should.

    Can anyone help me? The following is the code written in ProRealTime:

    // === Coefficienti High-Pass ===
    a1HP = EXP(-(SQRT(2) * 3.14159) / HPLength)
    b1HP = 2 * a1HP * COS((SQRT(2) * 180) / HPLength)
    c2HP = b1HP
    c3HP = -(a1HP * a1HP)
    c1HP = (1 + c2HP - c3HP)/4
    
    // === High-Pass Filter ===
    IF BarIndex >= 4 THEN
       HP = c1HP * (Close - 2*Close[1] + Close[2]) + c2HP * HP[1] + c3HP * HP[2]
    ELSE
       HP = 0
    ENDIF
    
    // === Coefficienti Super Smoother ===
    a1SS = EXP(-(SQRT(2) * 3.14159) / LPLength)
    b1SS = 2 * a1SS * COS((SQRT(2) * 180) / LPLength)
    c2SS = b1SS
    c3SS = -(a1SS * a1SS)
    c1SS = 1 - c2SS - c3SS
    
    // === Super Smoother ===
    IF BarIndex >= 4 THEN
       SS = c1SS * (HP + HP[1]) / 2 + c2SS * SS[1] + c3SS * SS[2]
    ELSE
       SS = HP
    ENDIF
    
    // === RMS ===
    SumSq = 0
    FOR Count = 0 to RMSLength - 1 DO
       Sumsq = SumSq + SS[count]*SS[Count]
    NEXT
    
    IF SumSq <> 0 THEN
       RMS = SQR(SumSq/RMSLength)
    ENDIF
    
    
    // === Cybernetic Oscillator ===
    IF RMS <> 0 THEN
       CyberneticOscillator = SS / RMS
    ENDIF
    
    RETURN CyberneticOscillator AS "Cybenrnetic Oscillator"
    
    The variables HPLength, LPLength and RMSLength are set as parameters in the ProBuilder code editor.
    I attached also a screenshot of the behaviour of the CO, applied to the graph of the NASDAQ Index.
    Screenshot-2025-09-29-143314.png Screenshot-2025-09-29-143314.png
    #252008 quote
    robertogozzi
    Moderator
    Master

    The PDF file is missing, if you can’t attach it, please post the text of the code.

    #252044 quote
    Iván González
    Moderator
    Master

    Hi! I found the oscillator in trading view.

    // ====================================================
    //PRC_Cybernetic Oscillator (John Ehlers, TASC 2025)
    //version = 0
    //01.10.25
    //Iván González @ www.prorealcode.com
    //Sharing ProRealTime knowledge
    // ====================================================
    // ----- Parámetros
    hpPeriod = 30       // Periodo filtro Highpass
    lpPeriod = 20       // Periodo filtro Lowpass (Super Smoother)
    rmsLen   = 100      // Longitud RMS
    threshold = 1       // Umbral opcional
    // ----- Constantes
    pi = 3.1415926535
    sqrt2 = 1.41421356237
    src = close
    // ====================================================
    // Calculos
    // ====================================================
    if barindex>=4 then
       // ----- High-Pass Filter (2nd order)
       a0 = sqrt2 * pi / hpPeriod
       a1 = EXP(-a0)
       c2hp = 2*a1*COS(a0*180/pi)
       c3hp = -(a1*a1)
       c1hp = (1 + c2hp - c3hp) * 0.25
       
       hp = 0
       hp = c1hp * (src - 2*src[1] + src[2]) + c2hp*hp[1] + c3hp*hp[2]
       
       // ----- Super Smoother (Low-Pass, 2nd order)
       a0lp = sqrt2 * pi / lpPeriod
       a1lp = EXP(-a0lp)
       c2lp = 2*a1lp*COS(a0lp*180/pi)
       c3lp = -(a1lp*a1lp)
       c1lp = 1 - c2lp - c3lp
       
       lp = 0
       lp = c1lp * 0.5*(hp + hp[1]) + c2lp*lp[1] + c3lp*lp[2]
    endif
    // ====================================================
    // RMS Normalization
    // ====================================================
    pow2 = lp*lp
    rms = SQRT(Average[rmsLen](pow2))
    epsilon = 0.000001
    den = MAX(rms, epsilon)
    
    osc = lp / den
    // ====================================================
    // Líneas de referencia
    // ====================================================
    zeroline = 0
    upth = threshold
    lowth = -threshold
    if osc > 0 then
       red=0
       green=255
       blue=0
    else
       red=255
       green=0
       blue=0
    endif
    // ====================================================
    RETURN osc AS "Cybernetic Osc" coloured(red,green,blue)style(line,3),zeroline COLOURED(200,200,200) AS "0",upth COLOURED(150,150,150) AS "+Threshold",lowth COLOURED(150,150,150) AS "-Threshold"
    
    elekin. thanked this post
    #252061 quote
    elekin.
    Participant
    New

    Ops, sorry, It hasn’t been uploaded. I’ll try again, if it doesn’t work, here is the code, written in EasyLanguage from the original file:

    High-Pass filter:

    {
    Highpass Function
    (C) 2004-2024 John F. Ehlers
    }
    Inputs:
    Price(numericseries),
    Period(numericsimple);
    Vars:
    a1(0),
    b1(0),
    c1(0),
    c2(0),
    c3(0);
    a1 = expvalue(-1.414*3.14159 / Period);
    b1 = 2*a1*Cosine(1.414*180 / Period);
    c2 = b1;
    c3 = -a1*a1;
    c1 = (1 + c2 – c3) / 4;
    If CurrentBar >= 4 Then $HighPass = c1*(Price – 2*Price[1] +
    Price[2]) + c2*$HighPass[1] + c3*$HighPass[2];
    If Currentbar < 4 Then $HighPass = 0; Super Smoother: { SuperSmoother Function (C) 2004-2025 John F. Ehlers } Inputs: Price(numericseries), Period(numericsimple); Vars: a1(0), b1(0), c1(0), c2(0), c3(0); a1 = expvalue(-1.414*3.14159 / Period); b1 = 2*a1*Cosine(1.414*180 / Period); c2 = b1; c3 = -a1*a1; c1 = 1 - c2 - c3; If CurrentBar >= 4 Then $SuperSmoother =
    c1*(Price + Price[1]) / 2 + c2*$SuperSmoother[1] +
    c3*$SuperSmoother[2];
    If Currentbar < 4 Then $SuperSmoother = Price; Root Mean Square: { RMS Function (C) 2015-2025 John F. Ehlers } Inputs: Price(numericseries), Length(numericsimple); Vars: SumSq(0), count(0); SumSq = 0; for count = 0 to Length - 1 Begin SumSq = SumSq + Price[count]*Price[count]; End; If SumSq <> 0 Then $RMS = SquareRoot(SumSq / Length);

    Final formula of the Cybernetic Oscillator:

    {
    Cybernetic Oscillator
    (C) 2025 John F. Ehlers
    }
    Inputs:
    HPLength(30),
    LPLength(20);
    Vars:
    HP(0),
    LP(0),
    RMS(0),
    CyberneticOsc(0);
    HP = $HighPass(Close, HPLength);
    LP = $SuperSmoother(HP, LPLength);
    RMS = $RMS(LP, 100);
    If RMS <> 0 Then CyberneticOsc = LP / RMS;
    Plot1(CyberneticOsc);
    Plot2(0);

    Cybernetic-Oscillator_compressed.pdf
    #252066 quote
    elekin.
    Participant
    New

    Thanks!
    I did wrong something about the RMS formula, I guess, now the values are way more stable and the same of the cybernetic oscillator posted on TradingView.

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

Cybernetic Oscillator by John F. Ehlers


ProBuilder: Indicators & Custom Tools

New Reply
Author
author-avatar
elekin. @elekin Participant
Summary

This topic contains 4 replies,
has 3 voices, and was last updated by elekin.
5 months ago.

Topic Details
Forum: ProBuilder: Indicators & Custom Tools
Language: English
Started: 09/29/2025
Status: Active
Attachments: 2 files
Logo Logo
Loading...