Digitale filters voor traders

Kant-en-klare, geteste indicatoren en handelssystemen
Plaats reactie
Eric
Berichten: 2936
Lid geworden op: za sep 10, 2005 2:41 am
Locatie: Den Haag

Digitale filters voor traders

Bericht door Eric » za apr 12, 2008 6:56 pm

Als aanvulling op de presentatie op het Wall Street seminar in Bunnik (12/4/08) en het artikel in Traders Bulletin (oktober 2008) hierbij een aantal indicatoren van John Ehlers op een rij.

De presentatie in Bunnik is bijgeevoegd in PowerPoint formaat.

Voor diegenen die meer willen lezen van Ehlers zijn de boeken verkrijgbaar bij amazon.com.

MESA and Trading Market Cycles
Rocket Science for Traders

---
Eric
Je hebt niet voldoende permissies om de bijlagen van dit bericht te bekijken.
Laatst gewijzigd door Eric op di okt 21, 2008 6:04 pm, 2 keer totaal gewijzigd.

Eric
Berichten: 2936
Lid geworden op: za sep 10, 2005 2:41 am
Locatie: Den Haag

Bericht door Eric » za apr 12, 2008 7:01 pm

Enkelvoudige sinusgenerator:

Code: Selecteer alles

{- Filename: Sinus -}

var
  Amplitude, Fase: real;
  i, Periode, Cycles: integer;
  sSinus: TSeries;
begin
{ Indicator parameters }
  Periode := CreateParameterInteger('Periode (bars)', 1, 999, 30, true);
  Amplitude := CreateParameterInteger('Amplitude', 1, 999, 100, true);
  Fase := CreateParameterInteger('Fase (bars)', -999, 999, 0, true);
  Cycles := CreateParameterInteger('Aantal cycles', 1, 999999, 10, true);

  sSinus := CreateSeries(BarCount);
  for i:=BarCount-1 downto MaxInt(0, BarCount - Cycles*Periode - 1) do
  begin
    sSinus[i] := Sin(2 * Pi * (BarCount-1-i-Fase) / Periode) * Amplitude;
  end;
  
{ Indicatorberekening (als voorbeeld hier een moving average) }
  with CreateLine(sSinus) do
  begin
    Name := 'Sinus';
    Color := clLime;
  end;
  with CreateLine(FillSeries(CreateSeries(BarCount), 0)) do
  begin
    Name := '0';
    Color := clSilver;
  end;
end.
---
Eric

Eric
Berichten: 2936
Lid geworden op: za sep 10, 2005 2:41 am
Locatie: Den Haag

Bericht door Eric » za apr 12, 2008 7:03 pm

Sinusgenerator met 2de hoogfrequente (10x basisfrequentie) sinuscomponent.

Code: Selecteer alles

{- Filename: Sinus2 -}

var
  Amplitude, Fase: real;
  i, Periode, Cycles: integer;
  sSinus: TSeries;
begin
{ Indicator parameters }
  Periode := CreateParameterInteger('Periode (bars)', 1, 999, 200, true);
  Amplitude := CreateParameterInteger('Amplitude', 1, 999, 100, true);
  Fase := CreateParameterInteger('Fase (bars)', -999, 999, 0, true);
  Cycles := CreateParameterInteger('Aantal cycles', 1, 999999, 10, true);

  sSinus := CreateSeries(BarCount);
  for i:=BarCount-1 downto MaxInt(0, BarCount-1-Periode*Cycles) do
  begin
    sSinus[i] := Sin(2 * Pi * (BarCount-1-i-Fase) / Periode) * Amplitude +
                 Sin(2 * Pi * i / (Periode/10)) * Amplitude / 10;
  end;
  
{ Indicatorberekening (als voorbeeld hier een moving average) }
  with CreateLine(sSinus) do
  begin
    Name := 'Sinus';
    Color := clLime;
  end;
  with CreateLine(FillSeries(CreateSeries(BarCount), 0)) do
  begin
    Name := '0';
    Color := clSilver;
  end;
end.
---
Eric

Eric
Berichten: 2936
Lid geworden op: za sep 10, 2005 2:41 am
Locatie: Den Haag

Bericht door Eric » za apr 12, 2008 7:06 pm

Ehlers Homodyne Discriminator. Deze indicator geeft de frequentie van de dominante golf in de koersen aan.

Credits voor PaulM die het grootste deel van de codering in TA-script reeds had gedaan voor de Sine Wave.

Code: Selecteer alles

{- Filename: Ehlers Homodyne Discriminator -}

function Hilbert(S: TSeries): TSeries;
var
  S2, S4, S6: TSeries;
begin
  S2 := ShiftSeries(S, 2);
  S4 := ShiftSeries(S, 4);
  S6 := ShiftSeries(S, 6);
  Result := SubtractSeries(SubtractSeries(AddSeries(MultiplySeriesBy(S,0.0962), MultiplySeriesBy(S2, 0.5769)), MultiplySeriesBy(S4,0.5769)), MultiplySeriesBy(S6,0.0962));
end;

var
  Smooth, Smooth2, Smooth4, Smooth6, RawDetrender, Detrender: TSeries;
  Price, DC: TSeries;
  I1, Q1: TSeries;
  i: integer;
  Period, PrevPeriod, jI, jQ, I2, Q2, PrevI2, PrevQ2,
  Re, Im, PrevRe, PrevIm, SmoothPeriod, PrevSmoothPeriod: real;
begin
  with Indicator do
  begin
    RequiredBars := 10;
  end;

  Price := DivideSeriesBy(AddSeries(High, Low), 2);
  Smooth := MA(Price, maWeighted, 4);
  RawDetrender := Hilbert(Smooth);

  Detrender := FillSeries(CreateSeries(BarCount), 0);
  DC := CreateSeries(BarCount);
  Q1 := CreateSeries(BarCount);
  I1 := CreateSeries(BarCount);

  for i:=FirstValidIndex(RawDetrender) to BarCount-1 do
  begin
    Detrender[i] := RawDetrender[i]*(0.075*PrevPeriod + 0.54);

// Compute InPhase and Quadrature components
    I1[i] := Detrender[i-3];
    Q1[i] := (0.0962*Detrender[i] + 0.5769*Detrender[i-2] - 0.5769*Detrender[i-4] - 0.0962*Detrender[i-6])*(0.075*PrevPeriod + 0.54);
// Advance the phase of I1 and Q1 by 90 degrees
    if IsValid(I1[i-6])and IsValid(Q1[i-6]) then
    begin
      jI := (0.0962*I1[i] + 0.5769*I1[i-2] - 0.5769*I1[i-4] - 0.0962*I1[i-6])*(0.075*PrevPeriod + 0.54);
      jQ := (0.0962*Q1[i] + 0.5769*Q1[i-2] - 0.5769*Q1[i-4] - 0.0962*Q1[i-6])*(0.075*PrevPeriod + 0.54);
    end;
// Phasor addition for 3 bar averaging
    PrevI2 := I2;
    PrevQ2 := Q2;
    I2 := I1[i] - jQ;
    Q2 := Q1[i] + jI;

// Smooth the I and Q components before applying the discriminator
    I2 := 0.2*I2 + 0.8*PrevI2;
    Q2 := 0.2*Q2 + 0.8*PrevQ2;

// Homodyne Discriminator
    PrevRe := Re;
    PrevIm := Im;
    Re := I2*PrevI2 + Q2*PrevQ2;
    Im := I2*PrevQ2 - Q2*PrevI2;
    Re := 0.2*Re + 0.8*PrevRe;
    Im := 0.2*Im + 0.8*PrevIm;

    PrevPeriod := Period;
    if (Im <> 0) and (Re <> 0) then Period := 360/(180/Pi*ArcTan(Im/Re));
    if Period > 1.5*PrevPeriod then Period := 1.5*PrevPeriod;
    if Period < 0.67*PrevPeriod then Period := 0.67*PrevPeriod;
    if Period < 6 then Period := 6;
    if Period > 50 then Period := 50;
    Period := 0.2*Period + 0.8*PrevPeriod;
    PrevSmoothPeriod := SmoothPeriod;
    SmoothPeriod := 0.33*Period + 0.67*PrevSmoothPeriod;
    DC[i] := SmoothPeriod;
  end;

  with CreateLine(DC) do
  begin
    Name := 'DC';
    Color := clYellow;
  end;
end.
---
Eric

Eric
Berichten: 2936
Lid geworden op: za sep 10, 2005 2:41 am
Locatie: Den Haag

Bericht door Eric » za apr 12, 2008 7:12 pm

Ehlers Instantaneous Trendline.

Credits voor PaulM die het grootste deel van de codering in TA-script reeds had gedaan voor de Sine Wave.

Code: Selecteer alles

{- Filename: Ehlers Instantaneous Trendline -}

var
  Smooth, Smooth2, Smooth4, Smooth6, RawDetrender, Detrender: TSeries;
  Price, DC: TSeries;
  I1, Q1, ITrend, TrendLine: TSeries;
  i, j, ICount: integer;
  Period, PrevPeriod, jI, jQ, I2, Q2, PrevI2, PrevQ2, ISum,
  Re, Im, PrevRe, PrevIm, SmoothPeriod, PrevSmoothPeriod: real;
begin
  with Indicator do
  begin
    NewBand := false;
    ScaleRange := srCommon;
    RequiredBars := 20;
  end;

  Price := DivideSeriesBy(AddSeries(High, Low), 2);
  Smooth := MA(Price, maWeighted, 4);
  Smooth2 := ShiftSeries(Smooth, 2);
  Smooth4 := ShiftSeries(Smooth, 4);
  Smooth6 := ShiftSeries(Smooth, 6);
  RawDetrender := SubtractSeries(SubtractSeries(AddSeries(MultiplySeriesBy(Smooth,0.0962) ,MultiplySeriesBy(Smooth2, 0.5769)), MultiplySeriesBy(Smooth4,0.5769)) , MultiplySeriesBy(Smooth6,0.0962));

  Detrender := FillSeries(CreateSeries(BarCount), 0);
  DC := CreateSeries(BarCount);
  Q1 := CreateSeries(BarCount);
  I1 := CreateSeries(BarCount);

  ITrend := CreateSeries(BarCount);

  for i:=FirstValidIndex(RawDetrender) to BarCount-1 do
  begin
    Detrender[i] := RawDetrender[i]*(0.075*PrevPeriod + 0.54);

// Compute InPhase and Quadrature components
    Q1[i] := (0.0962*Detrender[i] + 0.5769*Detrender[i-2] - 0.5769*Detrender[i-4] - 0.0962*Detrender[i-6])*(0.075*PrevPeriod + 0.54);
    I1[i] := Detrender[i-3];
// Advance the phase of I1 and Q1 by 90 degrees
    if IsValid(I1[i-6])and IsValid(Q1[i-6]) then
    begin
      jI := (0.0962*I1[i] + 0.5769*I1[i-2] - 0.5769*I1[i-4] - 0.0962*I1[i-6])*(0.075*PrevPeriod + 0.54);
      jQ := (0.0962*Q1[i] + 0.5769*Q1[i-2] - 0.5769*Q1[i-4] - 0.0962*Q1[i-6])*(0.075*PrevPeriod + 0.54);
    end;
// Phasor addition for 3 bar averaging
    PrevI2 := I2;
    PrevQ2 := Q2;
    I2 := I1[i] - jQ;
    Q2 := Q1[i] + jI;

// Smooth the I and Q components before applying the discriminator
    I2 := 0.2*I2 + 0.8*PrevI2;
    Q2 := 0.2*Q2 + 0.8*PrevQ2;

// Homodyne Discriminator
    PrevRe := Re;
    PrevIm := Im;
    Re := I2*PrevI2 + Q2*PrevQ2;
    Im := I2*PrevQ2 - Q2*PrevI2;
    Re := 0.2*Re + 0.8*PrevRe;
    Im := 0.2*Im + 0.8*PrevIm;

    PrevPeriod := Period;
    if (Im <> 0) and (Re <> 0) then Period := 360/(180/Pi*ArcTan(Im/Re));
    if Period > 1.5*PrevPeriod then Period := 1.5*PrevPeriod;
    if Period < 0.67*PrevPeriod then Period := 0.67*PrevPeriod;
    if Period < 6 then Period := 6;
    if Period > 50 then Period := 50;
    Period := 0.2*Period + 0.8*PrevPeriod;
    PrevSmoothPeriod := SmoothPeriod;
    SmoothPeriod := 0.33*Period + 0.67*PrevSmoothPeriod;

// compute trendline as simple average over the measured dominant cycle period
    ICount := 0;
    ISum := 0;
    for j:=0 to MinInt(i, trunc(SmoothPeriod + 0.5)-1) do
    begin
      ISum := ISum + Price[i-j];
      ICount := ICount+1;
    end;
    if ICount > 0 then ITrend[i] := ISum / ICount;
  end;
  
  TrendLine := MA(ITrend, maWeighted, 4);

  with CreateLine(TrendLine) do
  begin
    Name := 'TrendLine';
    Color := clYellow;
  end;
  with CreateLine(Smooth) do
  begin
    Name := 'Smooth';
    Color := clWhite;
  end;
end.
---
Eric

Eric
Berichten: 2936
Lid geworden op: za sep 10, 2005 2:41 am
Locatie: Den Haag

Bericht door Eric » za apr 12, 2008 7:15 pm


Eric
Berichten: 2936
Lid geworden op: za sep 10, 2005 2:41 am
Locatie: Den Haag

Bericht door Eric » ma apr 21, 2008 2:49 pm

Niet in de presentatie behandeld maar ook van Ehlers: de Fisher transform.

---
Eric

Plaats reactie