Auto Envelope van dr. Alexander Elder

Stel hier uw vragen over TA-script, of help anderen met het oplossen van hun probleem
Plaats reactie
Optiontrader
Berichten: 368
Lid geworden op: ma jan 01, 2007 9:41 pm

Auto Envelope van dr. Alexander Elder

Bericht door Optiontrader »

Beste Eric,

Hieronder het script van Auto Envelope Indicator van dr. Alexander Elder.

Een vraag over een scan mogelijkheid:

De prijs van een aandeel (bijv. Gartner) bevindt zich tussen de Middle Channel Line en Lower Channel Line (zie situatie in de bijlasge).

Is het mogelijk om dat naar voren te krijgen bij het scannen?

Uiteraard ook bij situatie tussen Upper Channel Line and Middle Channel Line

Het raken van beide lijnen moet dan niet in de scan mogelijkheid zitten, want die mogelijkheid heb je al gemaakt en werkt naar behoren.

Groet OT

Code: Selecteer alles

{- Filename: 4 TAR Auto Envelope -}

    (**************************************************************
    Indicator gemaakt op: 10-Nov-07
    Auteur: <Wessel de Roode>
    Indicator idee Dr. Alexander Elder: Come into my trading room
    ***************************************************************)

    // Whipe start waarden
    procedure CleanSeries(s: TSeries; Offset, Lookback: integer);
    var
      i: integer;
    begin
      for i:=0 to GetArrayLength(s)-1-Offset-Lookback do s[i] := NaN;
      for i:=GetArrayLength(s)-Offset to GetArrayLength(s)-1 do s[i] := NaN;
    end;

    // QSort met dank aan Eric van ta-script forum
    procedure _QSort(Data: TSeries; Lower, Upper: integer);
    var
      Left, Right: integer;
      Pivot, tmp: real;
    begin
      if GetArrayLength(Data) = 0 then Exit;

      Pivot := Data[(lower+upper) div 2];
      Left := lower;
      Right := upper;

      while Left <= Right do
      begin
        while Data[Left] < Pivot do Left := Left+1;  { Parting for left }
        while Data[Right] > Pivot do Right := Right-1;{ Parting for right}
        if Left <= Right then   { Validate the change }
        begin
          tmp := Data[Left];
          Data[left] := Data[Right];
          Data[Right] := tmp;
          Left := Left+1;
          Right := Right-1;
        end;
      end;
      if Right > Lower then _QSort(Data, lower, right); { Sort the LEFT  part }
      if Upper > Left  then _QSort(Data, left, upper); { Sort the RIGHT part }
    end;

    function LastValidIndex(Values: TSeries): integer;
    begin
      Result := GetArrayLength(Values)-1;
      while (Result > 0) and IsNaN(Values[Result]) do Result := Result-1;
    end;

    // QSort met dank aan Eric van ta-script forum
    procedure QSort(Values: TSeries);
    begin
      _QSort(Values, FirstValidIndex(Values), LastValidIndex(Values));
    end;

    function CopySerie(S: TSeries; Offset, Lookback: integer): TSeries;
    var
      i, l: integer;
      tmp: TSeries;
    begin
      tmp := CreateSeries(Lookback);
      l := GetArrayLength(S);
      if l < lookback then
      begin
        exit;
      end;
      for i:=0 to Lookback-1 do tmp[i] := S[l-Lookback+i-Offset];
      Result := tmp;
    end;

    var
    { declaraties }
      SlowEMAPeriod, i                : integer;  // parameterwaarde EMA
      Count                           : integer;  // Tel aantal doorprikkende bars
      EMASeries, Maxies,Minies        : TSeries;  // Series
      UpperChannel, LowerChannel      : TSeries;  // Series
      Offset, LookBack                : integer;  // parameterwaarde Look back period
      Pct                             : real;     // Procent van de bars binnen het channel
      ShiftUpper                      : real; // Upperband shift
      ShiftLower                      : real; // Lowerband shift
      MarkerType: integer;
    begin

    { Indicator parameters }
      SlowEMAPeriod := CreateParameterInteger('EMA', 1, 999, 22, true);
      Offset := CreateParameterInteger('Offset', 0, 999, 0, true);
      LookBack := CreateParameterInteger('Look back period', 1, 999, 100, true);
      Pct := CreateParameterReal('% Bars Within Channel',0, 100, 95, true)/100.0;
      MarkerType := CreateParameterSelect('Marker triggered by', 'No markers'#9'Lower band crossing'#9'Mid line crossing'#9'Upper band crossing'#9'Open above upper band'#9'Open below lower band', 0, false);

    { Indicator eigenschappen }
      with Indicator do
      begin
        ShortName := 'AutoEnvelope';  // naam boven grafiek
        RequiredBars := Offset+Lookback+5*SlowEMAPeriod;  // aantal benodige koersen om eerste indicatorwaarde te berekenen
        NewBand := false;  // indicator komt door hoofdgrafiek heen
        ScaleRange := srCommon;  // indicatorschaal is identiek aan de hoofdgrafiek
        CanUseParentDelta := true;  // we kunnen ook het verschil met de hoofdgrafiek weergeven
        SignalView := svShowInMain;
      end;

      Count := Round( LookBack * (1.0 - Pct) );

      { EMA Trend Line }
      EMASeries := MA(Close, maExponential, SlowEmaPeriod);
      Maxies := SubtractSeries(High, EMASeries);
      Maxies := CopySerie(Maxies, Offset, Lookback);
      QSort(Maxies);

      Minies := SubtractSeries(EMASeries, Low);
      Minies := CopySerie(Minies, Offset, Lookback);
      QSort(Minies);

      if (GetArrayLength(Maxies) > Count) and IsValid(Maxies[GetArrayLength(Maxies)-Count]) then
        ShiftUpper := Maxies[GetArrayLength(Maxies)-Count];
      UpperChannel := IncSeries(EMASeries, ShiftUpper);
      CleanSeries(UpperChannel, Offset, Lookback);

      if (GetArrayLength(Minies) > Count) and IsValid(Minies[ GetArrayLength(Minies)-Count]) then
        ShiftLower := Minies[ GetArrayLength(Minies)-Count ];
      LowerChannel := IncSeries(EMASeries,-ShiftLower);
      CleanSeries(LowerChannel, Offset, Lookback);

      for i:=FirstValidIndex(LowerChannel)+1 to BarCount-1 do
      begin
        case MarkerType of
          1: if (Close[i-1] < LowerChannel[i]) and (High[i] > LowerChannel[i]) then Mark(i);
          2: if (Close[i-1] < EMASeries[i]) and (High[i] > EMASeries[i]) then Mark(i);
          3: if (Close[i-1] < UpperChannel[i]) and (High[i] > UpperChannel[i]) then Mark(i);
          4: if (Open[i] > UpperChannel[i]) then Mark(i);
          5: if (Open[i] < LowerChannel[i]) then Mark(i);
        end;
      end;

      { Upper Channel Trend Line }
      with CreateLine(UpperChannel) do
      begin
        Name := 'UpperChannel';
        Color := clLtGray;
        LineType := ltClose;
        Visible := true;
      end;

      { EMA Trend Line }
      with CreateLine(EMASeries) do
      begin
        Name := 'EMA';
        Color := clYellow;
        LineType := ltClose;
        Visible := true;
      end;

      { Lower Channel Trend Line }
      with CreateLine(LowerChannel) do
      begin
        Name := 'LowerChannel';
        Color := clLtGray;
        LineType := ltClose;
        Visible := true;
      end;

    end.
Bijlagen
Situatie bij Gartner.GIF
Eric
Berichten: 3604
Lid geworden op: za sep 10, 2005 2:41 am
Locatie: Den Haag

Re: Auto Envelope van dr. Alexander Elder

Bericht door Eric »

Ik heb twee nieuwe markeringsopties toegevoegd:

Code: Selecteer alles

{- Filename: 4 TAR Auto Envelope -}

    (**************************************************************
    Indicator gemaakt op: 10-Nov-07
    Auteur: <Wessel de Roode>
    Indicator idee Dr. Alexander Elder: Come into my trading room
    ***************************************************************)

    // Whipe start waarden
    procedure CleanSeries(s: TSeries; Offset, Lookback: integer);
    var
      i: integer;
    begin
      for i:=0 to GetArrayLength(s)-1-Offset-Lookback do s[i] := NaN;
      for i:=GetArrayLength(s)-Offset to GetArrayLength(s)-1 do s[i] := NaN;
    end;

    // QSort met dank aan Eric van ta-script forum
    procedure _QSort(Data: TSeries; Lower, Upper: integer);
    var
      Left, Right: integer;
      Pivot, tmp: real;
    begin
      if GetArrayLength(Data) = 0 then Exit;

      Pivot := Data[(lower+upper) div 2];
      Left := lower;
      Right := upper;

      while Left <= Right do
      begin
        while Data[Left] < Pivot do Left := Left+1;  { Parting for left }
        while Data[Right] > Pivot do Right := Right-1;{ Parting for right}
        if Left <= Right then   { Validate the change }
        begin
          tmp := Data[Left];
          Data[left] := Data[Right];
          Data[Right] := tmp;
          Left := Left+1;
          Right := Right-1;
        end;
      end;
      if Right > Lower then _QSort(Data, lower, right); { Sort the LEFT  part }
      if Upper > Left  then _QSort(Data, left, upper); { Sort the RIGHT part }
    end;

    function LastValidIndex(Values: TSeries): integer;
    begin
      Result := GetArrayLength(Values)-1;
      while (Result > 0) and IsNaN(Values[Result]) do Result := Result-1;
    end;

    // QSort met dank aan Eric van ta-script forum
    procedure QSort(Values: TSeries);
    begin
      _QSort(Values, FirstValidIndex(Values), LastValidIndex(Values));
    end;

    function CopySerie(S: TSeries; Offset, Lookback: integer): TSeries;
    var
      i, l: integer;
      tmp: TSeries;
    begin
      tmp := CreateSeries(Lookback);
      l := GetArrayLength(S);
      if l < lookback then
      begin
        exit;
      end;
      for i:=0 to Lookback-1 do tmp[i] := S[l-Lookback+i-Offset];
      Result := tmp;
    end;

    var
    { declaraties }
      SlowEMAPeriod, i                : integer;  // parameterwaarde EMA
      Count                           : integer;  // Tel aantal doorprikkende bars
      EMASeries, Maxies,Minies        : TSeries;  // Series
      UpperChannel, LowerChannel      : TSeries;  // Series
      Offset, LookBack                : integer;  // parameterwaarde Look back period
      Pct                             : real;     // Procent van de bars binnen het channel
      ShiftUpper                      : real; // Upperband shift
      ShiftLower                      : real; // Lowerband shift
      MarkerType: integer;
    begin

    { Indicator parameters }
      SlowEMAPeriod := CreateParameterInteger('EMA', 1, 999, 22, true);
      Offset := CreateParameterInteger('Offset', 0, 999, 0, true);
      LookBack := CreateParameterInteger('Look back period', 1, 999, 100, true);
      Pct := CreateParameterReal('% Bars Within Channel',0, 100, 95, true)/100.0;
      MarkerType := CreateParameterSelect('Marker triggered by', 'No markers'#9'Lower band crossing'#9'Mid line crossing'#9
        'Upper band crossing'#9'Open above upper band'#9'Open below lower band'#9
        'Close > lower band & < mid line'#9'Close > mid line & < upper band', 0, false);

    { Indicator eigenschappen }
      with Indicator do
      begin
        ShortName := 'AutoEnvelope';  // naam boven grafiek
        RequiredBars := Offset+Lookback+5*SlowEMAPeriod;  // aantal benodige koersen om eerste indicatorwaarde te berekenen
        NewBand := false;  // indicator komt door hoofdgrafiek heen
        ScaleRange := srCommon;  // indicatorschaal is identiek aan de hoofdgrafiek
        CanUseParentDelta := true;  // we kunnen ook het verschil met de hoofdgrafiek weergeven
        SignalView := svShowInMain;
      end;

      Count := Round( LookBack * (1.0 - Pct) );

      { EMA Trend Line }
      EMASeries := MA(Close, maExponential, SlowEmaPeriod);
      Maxies := SubtractSeries(High, EMASeries);
      Maxies := CopySerie(Maxies, Offset, Lookback);
      QSort(Maxies);

      Minies := SubtractSeries(EMASeries, Low);
      Minies := CopySerie(Minies, Offset, Lookback);
      QSort(Minies);

      if (GetArrayLength(Maxies) > Count) and IsValid(Maxies[GetArrayLength(Maxies)-Count]) then
        ShiftUpper := Maxies[GetArrayLength(Maxies)-Count];
      UpperChannel := IncSeries(EMASeries, ShiftUpper);
      CleanSeries(UpperChannel, Offset, Lookback);

      if (GetArrayLength(Minies) > Count) and IsValid(Minies[ GetArrayLength(Minies)-Count]) then
        ShiftLower := Minies[ GetArrayLength(Minies)-Count ];
      LowerChannel := IncSeries(EMASeries,-ShiftLower);
      CleanSeries(LowerChannel, Offset, Lookback);

      for i:=FirstValidIndex(LowerChannel)+1 to BarCount-1 do
      begin
        case MarkerType of
          1: if (Close[i-1] < LowerChannel[i]) and (High[i] > LowerChannel[i]) then Mark(i);
          2: if (Close[i-1] < EMASeries[i]) and (High[i] > EMASeries[i]) then Mark(i);
          3: if (Close[i-1] < UpperChannel[i]) and (High[i] > UpperChannel[i]) then Mark(i);
          4: if (Open[i] > UpperChannel[i]) then Mark(i);
          5: if (Open[i] < LowerChannel[i]) then Mark(i);
          6: if (Close[i] > LowerChannel[i]) and (Close[i] < EMASeries[i]) then Mark(i);
          7: if (Close[i] > EMASeries[i]) and (Close[i] < UpperChannel[i]) then Mark(i);
        end;
      end;

      { Upper Channel Trend Line }
      with CreateLine(UpperChannel) do
      begin
        Name := 'UpperChannel';
        Color := clLtGray;
        LineType := ltClose;
        Visible := true;
      end;

      { EMA Trend Line }
      with CreateLine(EMASeries) do
      begin
        Name := 'EMA';
        Color := clYellow;
        LineType := ltClose;
        Visible := true;
      end;

      { Lower Channel Trend Line }
      with CreateLine(LowerChannel) do
      begin
        Name := 'LowerChannel';
        Color := clLtGray;
        LineType := ltClose;
        Visible := true;
      end;

    end.
--
Eric
Optiontrader
Berichten: 368
Lid geworden op: ma jan 01, 2007 9:41 pm

Re: Auto Envelope van dr. Alexander Elder

Bericht door Optiontrader »

Hallo Eric.

Op zich werkt het goed, maar het is juist de bedoeling dat de koers niet de 22 ema gedurende de dag raakt. Wanneer ie dat namelijk wel doet, daar hebben/scannen we de EMA Bounce voor!

Ik zie dat we nu van de close uitgaan, echter het is de bedoeling van de LOW uit te gaan, denk ik zo. Immers, wanneer de high of de low bijv niet de upper en middle line raakt gedurende dag, maar er wel tussen sluit, dan graag een signaal

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

Re: Auto Envelope van dr. Alexander Elder

Bericht door Eric »

Het is me nog niet helemaal duidelijk, welke lijn mag nu niet geraakt worden? Alleen de middelste (EMA) of ook de lower en upper?

Misschien zou je de voorwaarde als formule kunnen aangeven, zoals:
1 - hoog en laag van de bar beide tussen middle en upper line (dus gehele bar tussen de middle en upper line)
2 - hoog en laag van de bar beide tussen middle en lower line (dus gehele bar tussen de middle en lower line)

of

1 - slot en laag van de bar beide tussen middle en upper line (dus hoog mag boven upper line uitkomen)
2 - hoog en slot van de bar beide tussen middle en lower line (dus laag mag onder lower line uitkomen)

---
Eric
Optiontrader
Berichten: 368
Lid geworden op: ma jan 01, 2007 9:41 pm

Re: Auto Envelope van dr. Alexander Elder

Bericht door Optiontrader »

Eric,

Alleen de middelste niet!

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

Re: Auto Envelope van dr. Alexander Elder

Bericht door Eric »

Dus met deze condities:

1 - slot en laag van de bar beide tussen middle en upper line (dus hoog mag boven upper line uitkomen)
2 - hoog en slot van de bar beide tussen middle en lower line (dus laag mag onder lower line uitkomen)

geeft deze indicator een markering.

Code: Selecteer alles

{- Filename: 4 TAR Auto Envelope -}

    (**************************************************************
    Indicator gemaakt op: 10-Nov-07
    Auteur: <Wessel de Roode>
    Indicator idee Dr. Alexander Elder: Come into my trading room
    ***************************************************************)

    // Whipe start waarden
    procedure CleanSeries(s: TSeries; Offset, Lookback: integer);
    var
      i: integer;
    begin
      for i:=0 to GetArrayLength(s)-1-Offset-Lookback do s[i] := NaN;
      for i:=GetArrayLength(s)-Offset to GetArrayLength(s)-1 do s[i] := NaN;
    end;

    // QSort met dank aan Eric van ta-script forum
    procedure _QSort(Data: TSeries; Lower, Upper: integer);
    var
      Left, Right: integer;
      Pivot, tmp: real;
    begin
      if GetArrayLength(Data) = 0 then Exit;

      Pivot := Data[(lower+upper) div 2];
      Left := lower;
      Right := upper;

      while Left <= Right do
      begin
        while Data[Left] < Pivot do Left := Left+1;  { Parting for left }
        while Data[Right] > Pivot do Right := Right-1;{ Parting for right}
        if Left <= Right then   { Validate the change }
        begin
          tmp := Data[Left];
          Data[left] := Data[Right];
          Data[Right] := tmp;
          Left := Left+1;
          Right := Right-1;
        end;
      end;
      if Right > Lower then _QSort(Data, lower, right); { Sort the LEFT  part }
      if Upper > Left  then _QSort(Data, left, upper); { Sort the RIGHT part }
    end;

    function LastValidIndex(Values: TSeries): integer;
    begin
      Result := GetArrayLength(Values)-1;
      while (Result > 0) and IsNaN(Values[Result]) do Result := Result-1;
    end;

    // QSort met dank aan Eric van ta-script forum
    procedure QSort(Values: TSeries);
    begin
      _QSort(Values, FirstValidIndex(Values), LastValidIndex(Values));
    end;

    function CopySerie(S: TSeries; Offset, Lookback: integer): TSeries;
    var
      i, l: integer;
      tmp: TSeries;
    begin
      tmp := CreateSeries(Lookback);
      l := GetArrayLength(S);
      if l < lookback then
      begin
        exit;
      end;
      for i:=0 to Lookback-1 do tmp[i] := S[l-Lookback+i-Offset];
      Result := tmp;
    end;

    var
    { declaraties }
      SlowEMAPeriod, i                : integer;  // parameterwaarde EMA
      Count                           : integer;  // Tel aantal doorprikkende bars
      EMASeries, Maxies,Minies        : TSeries;  // Series
      UpperChannel, LowerChannel      : TSeries;  // Series
      Offset, LookBack                : integer;  // parameterwaarde Look back period
      Pct                             : real;     // Procent van de bars binnen het channel
      ShiftUpper                      : real; // Upperband shift
      ShiftLower                      : real; // Lowerband shift
      MarkerType: integer;
    begin

    { Indicator parameters }
      SlowEMAPeriod := CreateParameterInteger('EMA', 1, 999, 22, true);
      Offset := CreateParameterInteger('Offset', 0, 999, 0, true);
      LookBack := CreateParameterInteger('Look back period', 1, 999, 100, true);
      Pct := CreateParameterReal('% Bars Within Channel',0, 100, 95, true)/100.0;
      MarkerType := CreateParameterSelect('Marker triggered by', 'No markers'#9'Lower band crossing'#9'Mid line crossing'#9
        'Upper band crossing'#9'Open above upper band'#9'Open below lower band'#9
        'Bar in lower band'#9'Bar in upper band', 0, false);

    { Indicator eigenschappen }
      with Indicator do
      begin
        ShortName := 'AutoEnvelope';  // naam boven grafiek
        RequiredBars := Offset+Lookback+5*SlowEMAPeriod;  // aantal benodige koersen om eerste indicatorwaarde te berekenen
        NewBand := false;  // indicator komt door hoofdgrafiek heen
        ScaleRange := srCommon;  // indicatorschaal is identiek aan de hoofdgrafiek
        CanUseParentDelta := true;  // we kunnen ook het verschil met de hoofdgrafiek weergeven
        SignalView := svShowInMain;
      end;

      Count := Round( LookBack * (1.0 - Pct) );

      { EMA Trend Line }
      EMASeries := MA(Close, maExponential, SlowEmaPeriod);
      Maxies := SubtractSeries(High, EMASeries);
      Maxies := CopySerie(Maxies, Offset, Lookback);
      QSort(Maxies);

      Minies := SubtractSeries(EMASeries, Low);
      Minies := CopySerie(Minies, Offset, Lookback);
      QSort(Minies);

      if (GetArrayLength(Maxies) > Count) and IsValid(Maxies[GetArrayLength(Maxies)-Count]) then
        ShiftUpper := Maxies[GetArrayLength(Maxies)-Count];
      UpperChannel := IncSeries(EMASeries, ShiftUpper);
      CleanSeries(UpperChannel, Offset, Lookback);

      if (GetArrayLength(Minies) > Count) and IsValid(Minies[ GetArrayLength(Minies)-Count]) then
        ShiftLower := Minies[ GetArrayLength(Minies)-Count ];
      LowerChannel := IncSeries(EMASeries,-ShiftLower);
      CleanSeries(LowerChannel, Offset, Lookback);

      for i:=FirstValidIndex(LowerChannel)+1 to BarCount-1 do
      begin
        case MarkerType of
          1: if (Close[i-1] < LowerChannel[i]) and (High[i] > LowerChannel[i]) then Mark(i);
          2: if (Close[i-1] < EMASeries[i]) and (High[i] > EMASeries[i]) then Mark(i);
          3: if (Close[i-1] < UpperChannel[i]) and (High[i] > UpperChannel[i]) then Mark(i);
          4: if (Open[i] > UpperChannel[i]) then Mark(i);
          5: if (Open[i] < LowerChannel[i]) then Mark(i);
          6: if (Close[i] > LowerChannel[i]) and (High[i] < EMASeries[i]) then Mark(i);
          7: if (Low[i] > EMASeries[i]) and (Close[i] < UpperChannel[i]) then Mark(i);
        end;
      end;

      { Upper Channel Trend Line }
      with CreateLine(UpperChannel) do
      begin
        Name := 'UpperChannel';
        Color := clLtGray;
        LineType := ltClose;
        Visible := true;
      end;

      { EMA Trend Line }
      with CreateLine(EMASeries) do
      begin
        Name := 'EMA';
        Color := clYellow;
        LineType := ltClose;
        Visible := true;
      end;

      { Lower Channel Trend Line }
      with CreateLine(LowerChannel) do
      begin
        Name := 'LowerChannel';
        Color := clLtGray;
        LineType := ltClose;
        Visible := true;
      end;

    end.
---
Eric
Optiontrader
Berichten: 368
Lid geworden op: ma jan 01, 2007 9:41 pm

Re: Auto Envelope van dr. Alexander Elder

Bericht door Optiontrader »

Prima!
Plaats reactie