Point & Figure grafieken

Stel hier uw vragen over TA-script, of help anderen met het oplossen van hun probleem
Janus
Berichten: 1514
Lid geworden op: wo jan 30, 2008 2:07 am
Contacteer:

Point & Figure grafieken

Bericht door Janus »

Point & Figure P&F
Waarom Point & Figure grafieken?
Point & Figure (P&F) grafieken negeren tijd en tonen alleen significante prijsbewegingen,
waardoor ze veel ruis wegfilteren en zuivere steun- en weerstandsniveaus en trends geven.
In één zin: prijs-gedreven in plaats van tijd-gedreven.
Ik zie P&F grafieken als een analyse methode.
Afbeelding
Het grootste verschil is dat P&F geen vaste tijdsassen gebruikt: een kolom verandert alleen als de prijs een vooraf bepaalde boxgrootte beweegt of een reversal bereikt, waardoor alle kleine intra-periode ruis wordt geëlimineerd. Het voordeel is dat je daardoor heldere, objectieve steun- en weerstandsniveaus, breakout- en omkeersignalen krijgt zonder dat bewegende gemiddelden of andere tijdsafhankelijke indicatoren de interpretatie vertragen

P&F gebruikt een box size en een reversal-waarde; alleen wanneer de prijs met die boxgrootte beweegt wordt een X (stijgend) of O (dalend) toegevoegd, en bij een reversal start een nieuwe kolom. Daardoor ontstaan patronen en lijnen die direct prijsstructuur tonen: duidelijke trends, dubbele toppen/bodems en meetbare targets (projecties op basis van patroonhoogtes)

Wanneer P&F beter is dan tijdgebaseerde grafieken
• Voor trend- en breakout-handel: P&F geeft zuivere bevestiging van prijsdoorbraken zonder valse signalen door ruis.
• Voor position sizing en stops: box-based stops zijn logisch en consistent.
• Voor lange termijn of swing trading: minder gevoelig voor intraday ruis; signaalkwaliteit verbetert.
.
WallStreet for WIndows heeft een ingebouwde Point&Figure grafiek om weer te geven.
Waarom dan toch zelf iets ontwikkelen.
Dat is omdat ik enkele mogelijkheden mis, en ook omdat ik graag de grafiek in beeld heb waarop de P&F weergave gemaakt is.
Ik volg het meesterwerk op dit gebied wat geschreven is door Jeremy du Plessis (The Definitive Guide to Point and Figure ISBN: 9781897597637).
Wat bijvoorbeeld erg handig is bij weergave van intraday grafieken en een 1-box-reversal is de 'one step back' mogelijkheid.
Wat ik verder graag in de grafiek zie weergegeven is de target bepaling op basis van kolom tellingen.
Ook opent dit de mogelijkheid voor 'nieuwe toepassingen', waarover ik later meer zal vertellen.
Ik zit nog in de ontwikkelfase van de code, en aanpassingen zijn op dit moment gemakkelijker dan achteraf.
Wanneer u nu graag iets meegenomen wilt zien in de code, dan is dit het moment om dat aan te kaarten.
Ik plaats op dit moment de code nog niet, die heeft nog veel delen die gaan wijzigen, en ik moet er een vorm van handleiding bij schrijven.
Ik plaats hieronder vast even een plaatje wat uit de code rolt, op basis van een dag grafiek van de AEX bij een boxsize van 5 en een boxreversal van 3.
De trendlijnen die u ziet worden automatisch gegenereerd. De horizontale gele en lichtblauwe streepje zijn plaatsen waar de code een dubbele bodem (geel) op dubbele top doorbraak (blauw) heeft geconstateerd.

Grafiek:
Afbeelding

Stay tuned ..
Vriendelijke groet,
JanS ;)
Bakstenen
Berichten: 992
Lid geworden op: zo jul 19, 2015 7:51 pm

Re: Point & Figure grafieken

Bericht door Bakstenen »

Jan, hoe krijg ik een P%F in mijn grafiek?
Eric
Berichten: 3642
Lid geworden op: za sep 10, 2005 2:41 am
Locatie: Den Haag

Re: Point & Figure grafieken

Bericht door Eric »

Janus schreef: zo jan 04, 2026 11:14 pm Ik plaats op dit moment de code nog niet, die heeft nog veel delen die gaan wijzigen, en ik moet er een vorm van handleiding bij schrijven.

Stay tuned ..
Bakstenen
Berichten: 992
Lid geworden op: zo jul 19, 2015 7:51 pm

Re: Point & Figure grafieken

Bericht door Bakstenen »

Dat had ik gelezen Eric, maar kan je zien dat de dagen gaan tellen bij mij, ik dacht dat ik eens in een ver verleden een Pf grafiek in Ws had gemaakt, vandaar de vraag.
Maar dan was het in een ander programma
Janus
Berichten: 1514
Lid geworden op: wo jan 30, 2008 2:07 am
Contacteer:

Re: Point & Figure grafieken

Bericht door Janus »

Bakstenenen, Ik heb inderdaad de code nog niet geplaatst, maar wanneer je de P&F van Wallstreet for Windows zelf zoekt, die vind je in het menu 'Fonds'; zie plaatje.
Afbeelding
.
Vriendelijke groet,
JanS ;)
Bakstenen
Berichten: 992
Lid geworden op: zo jul 19, 2015 7:51 pm

Re: Point & Figure grafieken

Bericht door Bakstenen »

Dank Jan,
Dan ben ik nog niet dementerende
Janus
Berichten: 1514
Lid geworden op: wo jan 30, 2008 2:07 am
Contacteer:

Re: Point & Figure grafieken

Bericht door Janus »

.
Bijgevoegd de TA-Script code versie 1.00
.
Open een grafiek venster, en kies de P&F indicator, deze wordt dan in een nieuw venster geplaatst onder de koersgrafiek.
.
Wanneer u de grafiek uitzoomt ( er worden meer koersbars zichtbaar) dan zullen er ook meer kolommen in de P&F grafiek zichtbaar worden.
Wanneer u weer inzoomt in de koersgrafiek (minder koersbars zichtbaar) dan moet u om de P&F grafiek bij te werken even op F5 drukken.
.

Code: Selecteer alles

{- Filename: PointFigure_CountTargets_MinMaxScale_FontSize_With45Lines forum -}

{- PointFigure_CountTargets_MinMaxScale_FontSize_With45Lines
   P&F + DoubleTop/Bottom signals + Vertical/Horizontal count targets
   + sMinLine/sMaxLine scale forcing (NewBand)
   + Target text clamped to visible range (min/max)
   + Multiple parallel 45° lines (bull support / bear resistance)
   + © www.JSTAS.com
   + forum-versie 1.0  2026-01-12
-}

// --- Constants ---------------------------------------------------------------
const
  // --- HelpText -----------------------------
  sHelpText =
'Doel:'+#13+
'tekent een Point & Figure-grafiek (X = stijging, 0 = daling),optioneel met DoubleTop/Bottom signalen, targets en 45° trendlijnen (du Plessis).'+#13+
' P&F basis '+#13+
'> BoxSize: grootte van 1 box (koerspunten).' +#13+
'> ReversalBoxes: omkeerregel (aantal boxes tegen de trend voor nieuwe kolom).'+#13+
'> Use High/Low: '+#13+
'    True = klassiek (High/Low)'+#13+
'    False = Close-only (kan “gaten” geven)' +#13+
'> Max. Colums to Draw: max. aantal kolommen dat getekend wordt.' +#13+
'> Draw X/O: X/0-symbolen per box (anders streepjes per kolom).'  +#13+
'> Auto-switch to bars when crowded: bij te veel kolommen automatisch streepjes.'+#13+
'> MaxColsForXO: grens voor autoswitch.'  +#13+
'> SymbolStepBoxes: 1 = elk box-symbool, 2 = om de box, enz.' +#13+
'*'+#13+
'> Signalen:' +#13+
'> Draw DoubleTop/Bottom signals (B-(buy)/S-(sell)) tonen.'+#13+
'> BuySellSymbDist: extra spatie/afstand om B/S leesbaar te plaatsen.' +#13+
'> Buy/SellSignal Color: kleuren voor B/S.'+#13+
'*'+#13+
'Targets (counts)'+#13+
'> CountMethod: 0=None, 1=Vertical, 2=Horizontal(simple)'+#13+
'> CountMultiplier: meestal gelijk aan ReversalBoxes (maar je kunt variëren).'+#13+
'> Draw Count Targets: target-lijn aan/uit.'+#13+
'> TargetLineWidth: dikte target-lijn.'+#13+
'> ShowTargetText: targetwaarde als tekst.' +#13+
     'T^ = target boven beeld, Tv = target onder beeld.'+#13+
'> IncludeTargetsInScale: Y-as schaal rekening laten houden met targets.'+#13+
'> Buy/SellTarget Color: kleuren van targets.' +#13+
'> ScaleLookbackBars (0=all): schaal over laatste N bars (0 = alles).' +#13+
'> ScalePadBoxes: marge boven/onder in boxes.' +#13+
'*'+#13+
'Tekst en kleuren'+#13+
'> TextFontSize: lettergrootte X/0, B/S en targets.'+#13+
'> Background Color: achtergrond kleur.' +#13+
'> Bull/BearColumn Color: kleuren X en 0.'+#13+
'*'+#13+
' 45° trendlijnen (du Plessis)'+#13+
'> Show 45deg Trendlines: hoofdschakelaar.' +#13+
'> 45deg Bull Support: Bull trendlijnen aan/uit.'+#13+
'> 45deg Bear Resistance: Bear lijnen aan/uit.'+#13+
'> Trendline break needs valid signal: breuk pas geldig bij signaal (SELL resp. BUY).'+#13+
'> Max 45deg lines per side: max. parallelle lijnen.'+#13+
'> 45deg Line Width + Bull/BearTrendLine'+#13+
'> Color: stijl/kleuren.'+#13+
'> Bijvoorbeeld AEX dag: BoxSize=5, ReversalBoxes=3, Auto-switch aan, '+#13+
'    CountMethod=1 (Vertical), CountMultiplier=3, 45° lijnen aan.'+#13+'';
//
// ---------- functions and procedures -------
function ClampInt(v, lo, hi: integer): integer;
begin
  if v < lo then v := lo;
  if v > hi then v := hi;
  result := v;
end;
//
function AbsR(x: real): real;
begin
  if x < 0 then result := -x else result := x;
end;
//
function PriceToBox(p, boxSize: real): integer;
begin
  if boxSize <= 0 then
    result := 0
  else
    result := Trunc(p / boxSize);
end;
//
function BoxToPrice(b: integer; boxSize: real): real;
begin
  result := b * boxSize;
end;
//
procedure DrawSegDT(x1: TDateTime; y1: real; x2: TDateTime; y2: real; colr: integer; w: integer);
begin
  with CreateTrendLine(x1, y1, x2, y2) do
  begin
    Color := colr;
    Width := w;
  end;
end;
//
procedure DrawTextDT(x1: TDateTime; y1: real; txt: string; colr: integer; fontSz: integer);
begin
  with CreateText(x1, y1, txt) do
  begin
    Color := colr;
    Font.Size := fontSz;
    Font.Style := [];
    VertPosition := vpCenter;
    HorzPosition := hpLeft;
  end;
end;
//
function ClampRealToRange(v, lo, hi: real): real;
begin
  if v < lo then v := lo;
  if v > hi then v := hi;
  result := v;
end;
//
function ColAdjToBarIdx(colAdj, colsDraw, barCount: integer; index0IsCurrent: boolean): integer;
var
  t: real;
  idx: integer;
begin
  if colsDraw <= 1 then
    t := 0.5
  else
    t := colAdj / (colsDraw - 1.0);

  idx := Trunc(t * (barCount - 1) + 0.5);
  idx := ClampInt(idx, 0, barCount-1);

  if index0IsCurrent then
    idx := (barCount - 1) - idx;

  result := idx;
end;
//
// --- variables -------------
var
  { Parameters }
  BoxSize          : real;
  ReversalBoxes    : integer;
  UseHighLow       : boolean;
  Index0IsCurrent  : boolean;

  //DrawInNewBand    : boolean;
  MaxColsToDraw    : integer;

  DrawXO           : boolean;
  AutoSwitchXO     : boolean;
  MaxColsForXO     : integer;
  SymbolStepBoxes  : integer;

  DrawSignals      : boolean;
  
  { Colors }
  BckGrndColor       : TColor;
  BuySignalColor     : TColor;
  BuyTargetColor     : TColor;
  SellSignalColor    : TColor;
  SellTargetColor    : TColor;
  BullColumnColor    : TColor;
  BearColumnColor    : TColor;
  BullTrendLineColor : TColor;
  BearTrendLineColor : TColor;

  { Count targets }
  CountMethod      : integer; { 0=None, 1=Vertical, 2=Horizontal(simple) }
  ExplainCount     : boolean;
  ExplainCount2    : boolean;
  CountMultiplier  : integer; { meestal = ReversalBoxes }
  DrawCountTargets : boolean;
  TargetLineWidth  : integer;

  { Scale forcing }
  ScaleLookbackBars : integer; { 0=all }
  ScalePadBoxes     : integer; { marge in boxes }
  IncludeTargetsInScale : boolean;

 // ShowScaleLines   : boolean;
 // KeepYAxisButHideScaleLines : boolean;

  TextFontSize     : integer;
  BuySellSymbDist  : integer;
  FillUp           : string;
  ShowTargetText   : boolean;
  Helptekst        : string;

  { 45° trendlines }
  Show45Lines       : boolean;
  Show45Bull        : boolean;
  Show45Bear        : boolean;
  BreakNeedsSignal  : boolean;
  Max45LinesPerSide : integer;
  Line45Width       : integer;

  { Scale series (min/max) }
  sMinLine         : TSeries;
  sMaxLine         : TSeries;
  scaleMin         : real;
  scaleMax         : real;

  { Column storage }
  ColTopArr        : array of integer;  { box-index }
  ColBotArr        : array of integer;  { box-index }
  ColTypeArr       : array of integer;  { +1=X, -1=O }

  { Signal storage per column }
  SigTypeArr       : array of integer;  { +1 buy, -1 sell, 0 none }
  SigPriceArr      : array of real;     { breakout price }
  TargetPriceArr   : array of real;     { target price }

  { Engine state }
  k, i             : integer;
  hi, lo, cl       : real;
  hiB, loB, clB    : integer;
  baseB            : integer;
  baseSet          : boolean;

  colType          : integer;
  colTopB          : integer;
  colBotB          : integer;
  colIndex         : integer;

  { Drawing range }
  nCols            : integer;
  colsDraw         : integer;
  startCol         : integer;
  idx              : integer;

  { Drawing }
  colAdj           : integer;
  barIdx           : integer;
  xDT              : TDateTime;
  y1, y2           : real;
  colClr           : integer;

  { Target calc }
  boxesInCol       : integer;
  tgt              : real;
  brk              : real;
  wCount           : integer;
  j                : integer;

  { Scale calc }
  lookback         : integer;
  startChrono      : integer;
  tChrono          : integer;
  iData            : integer;
  scaleInit        : boolean;
  priceMin         : real;
  priceMax         : real;

  { Target text placement }
  yText            : real;
  txt              : string;

  { 45° drawing vars }
  eps              : real;
  lineStartCol     : integer;
  lineEndCol       : integer;
  lineY0           : real;
  lineYEnd         : real;
  cWalk            : integer;
  yLine            : real;
  tStart           : TDateTime;
  tEnd             : TDateTime;
  lineCount        : integer;
  breach           : boolean;
  useSignalBreach  : boolean;


begin
  { ===== Parameters ===== }
  BoxSize         := CreateParameterReal('BoxSize', 0.000001, 1000000, 5, true);
  ReversalBoxes   := CreateParameterInteger('ReversalBoxes', 1, 20, 3, true);
  UseHighLow      := CreateParameterBoolean('Use High/Low (anders Close-only)', false, true);

  MaxColsToDraw   := CreateParameterInteger('Max. Colums to Draw', 10, 400, 120, true);

  DrawXO          := CreateParameterBoolean('Draw X / 0', true, true);
  AutoSwitchXO    := CreateParameterBoolean('Auto-switch to bars when crowded', true, true);
  MaxColsForXO    := CreateParameterInteger('MaxColsForXO', 10, 300, 80, true);
  SymbolStepBoxes := CreateParameterInteger('SymbolStepBoxes (1=elk box)', 1, 10, 1, true);

  DrawSignals     := CreateParameterBoolean('Draw DoubleTop/Bottom signals', false, true);
  BuySellSymbDist := CreateParameterInteger('B-S-Column distance',0,6,2,false);

  CountMethod     := CreateParameterInteger('CountMethod: ', 0, 2, 1, true);
  ExplainCount    := CreateParameterBoolean('CountMethod --> 0=None, 1=Vertical, 2=Horizontal(simple)',false,false);
  CountMultiplier := CreateParameterInteger('CountMultiplier ', 1, 20, 3, true);
  ExplainCount2   := CreateParameterBoolean('Countmulitplier is usual equal ReversalBoxes', false, false);
  
  DrawCountTargets:= CreateParameterBoolean('Draw Count Targets', false, true);
  TargetLineWidth := CreateParameterInteger('TargetLineWidth', 1, 5, 1, true);
  ShowTargetText  := CreateParameterBoolean('ShowTargetText', false, true);
  TextFontSize    := CreateParameterInteger('TextFontSize', 6, 30, 8, true);

  ScaleLookbackBars := CreateParameterInteger('ScaleLookbackBars (0=all)', 0, 5000, 0, true);
  ScalePadBoxes     := CreateParameterInteger('ScalePadBoxes', 0, 50, 2, true);
  IncludeTargetsInScale := CreateParameterBoolean('IncludeTargetsInScale', false, true);

  { 45° trendlines parameters }
  Show45Lines       := CreateParameterBoolean('Show 45deg Trendlines', false, true);
  Show45Bull        := CreateParameterBoolean('45deg Bull Support', true, true);
  Show45Bear        := CreateParameterBoolean('45deg Bear Resistance', true, true);
  BreakNeedsSignal  := CreateParameterBoolean('Trendline break needs valid signal', true, true);
  Max45LinesPerSide := CreateParameterInteger('Max 45deg lines per side', 1, 50, 20, true);
  Line45Width       := CreateParameterInteger('45deg Line Width', 1, 5, 2, true);
  
  BckGrndColor       := CreateParameterColor('Background Color',clBlack);
  BuySignalColor     := CreateParameterColor('BuySignal  Color',clAqua);
  BuyTargetColor     := CreateParameterColor('BuyTarget  Color',clSilver);
  SellSignalColor    := CreateParameterColor('SellSignal Color',36095);
  SellTargetColor    := CreateParameterColor('SellTarget Color',clSilver);
  BullColumnColor    := CreateParameterColor('BullColumn Color X',clLime);
  BearColumnColor    := CreateParameterColor('BearColumn Color 0',clRed);
  BullTrendLineColor := CreateParameterColor('BullTrendLine Color',16744448);
  BearTrendLineColor := CreateParameterColor('BearTrendLine Color',4210943);
  
  with Indicator do
  begin
    RequiredBars := 1;
    NewBand      := true;
    ScaleRange   := srCommon;
    HiddenParams := true;
    HelpText     := sHelpText;
    ShortName    :='';
  end;
  
  with CreateRectangle(0,0,0,0) do
  begin
    X1Pct   := 0;
    X2Pct   := 100;
    Y1Pct   := 0;
    Y2Pct   := 100;
    Color   := BckGrndColor;
    bKColor := BckGrndColor;
  end;

   eps := BoxSize * 1e-6;

  { ===== CreateLine unconditional ===== }
  sMinLine := FillSeries(CreateSeries(BarCount), 0);
  sMaxLine := FillSeries(CreateSeries(BarCount), 0);

  with CreateLine(sMinLine) do
  begin
    Name := 'ScaleMin';
    Visible := true;
    Width := 1;
    Color := BckGrndColor;
  end;

  with CreateLine(sMaxLine) do
  begin
    Name := 'ScaleMax';
    Visible := true;
    Width := 1;
    Color := BckGrndColor;
  end;

  { guards }
  if (BarCount < 5) then Exit;
  if (BoxSize <= 0) then Exit;

  { ===== Arrays ===== }
  SetArrayLength(ColTopArr, BarCount);
  SetArrayLength(ColBotArr, BarCount);
  SetArrayLength(ColTypeArr, BarCount);

  SetArrayLength(SigTypeArr, BarCount);
  SetArrayLength(SigPriceArr, BarCount);
  SetArrayLength(TargetPriceArr, BarCount);

  for i := 0 to BarCount-1 do
  begin
    ColTopArr[i]  := 0;
    ColBotArr[i]  := 0;
    ColTypeArr[i] := 0;

    SigTypeArr[i]     := 0;
    SigPriceArr[i]    := 0;
    TargetPriceArr[i] := 0;
  end;

  { ===== Scale range basis: uit koersbars ===== }
  lookback := ScaleLookbackBars;
  if (lookback <= 0) or (lookback > BarCount) then lookback := BarCount;
  startChrono := BarCount - lookback;
  if startChrono < 0 then startChrono := 0;

  scaleInit := false;
  priceMin := 0;
  priceMax := 0;

  for tChrono := 0 to BarCount-1 do
  begin
    if Index0IsCurrent then
      iData := (BarCount-1) - tChrono
    else
      iData := tChrono;

    if tChrono >= startChrono then
    begin
      if not scaleInit then
      begin
        priceMin  := Low[iData];
        priceMax  := High[iData];
        scaleInit := true;
      end
      else
      begin
        if Low[iData] < priceMin then priceMin := Low[iData];
        if High[iData] > priceMax then priceMax := High[iData];
      end;
    end;
  end;

  if not scaleInit then
  begin
    priceMin := Close[BarCount-1];
    priceMax := Close[BarCount-1];
  end;

  { ===== Engine init ===== }
  colType  := 0;
  colIndex := -1;
  colTopB  := 0;
  colBotB  := 0;

  baseB := 0;
  baseSet := false;

  { ===== Engine: van oud -> nieuw ===== }
  for k := 0 to BarCount-1 do
  begin
    if Index0IsCurrent then
      i := (BarCount-1) - k
    else
      i := k;

    cl := Close[i];
    if UseHighLow then
    begin
      hi := High[i];
      lo := Low[i];
    end
    else
    begin
      hi := cl;
      lo := cl;
    end;

    clB := PriceToBox(cl, BoxSize);
    hiB := PriceToBox(hi, BoxSize);
    loB := PriceToBox(lo, BoxSize);

    if colType = 0 then
    begin
      if not baseSet then
      begin
        baseB := clB;
        baseSet := true;
      end;

      if hiB >= baseB + 1 then
      begin
        colType  := +1;
        colIndex := 0;
        colBotB  := baseB;
        colTopB  := hiB;
      end
      else
      if loB <= baseB - 1 then
      begin
        colType  := -1;
        colIndex := 0;
        colTopB  := baseB;
        colBotB  := loB;
      end;
    end
    else
    begin
      if colType = +1 then
      begin
        if hiB > colTopB then colTopB := hiB;

        if loB <= (colTopB - ReversalBoxes) then
        begin
          colIndex := colIndex + 1;
          colType  := -1;

          colTopB := colTopB - 1;
          colBotB := loB;
          if colBotB > colTopB then colBotB := colTopB;
        end;
      end
      else
      if colType = -1 then
      begin
        if loB < colBotB then colBotB := loB;

        if hiB >= (colBotB + ReversalBoxes) then
        begin
          colIndex := colIndex + 1;
          colType  := +1;

          colBotB := colBotB + 1;
          colTopB := hiB;
          if colTopB < colBotB then colTopB := colBotB;
        end;
      end;
    end;

    if colIndex >= 0 then
    begin
      ColTopArr[colIndex]  := colTopB;
      ColBotArr[colIndex]  := colBotB;
      ColTypeArr[colIndex] := colType;
    end;
  end;

  nCols := colIndex + 1;
  if nCols <= 0 then Exit;

  { ===== Determine draw window ===== }
  colsDraw := nCols;
  if colsDraw > MaxColsToDraw then colsDraw := MaxColsToDraw;

  startCol := nCols - colsDraw;
  if startCol < 0 then startCol := 0;

  { ===== Signals + Targets per column ===== }
  for idx := 2 to nCols-1 do
  begin
    SigTypeArr[idx] := 0;
    SigPriceArr[idx] := 0;
    TargetPriceArr[idx] := 0;

    { Double-top BUY }
    if (ColTypeArr[idx] = +1) and (ColTypeArr[idx-2] = +1) then
    begin
      if ColTopArr[idx] >= ColTopArr[idx-2] + 1 then
      begin
        brk := BoxToPrice(ColTopArr[idx-2] + 1, BoxSize);
        SigTypeArr[idx] := +1;
        SigPriceArr[idx] := brk;

        if DrawCountTargets and (CountMethod <> 0) then
        begin
          if CountMethod = 1 then
          begin
            boxesInCol := (ColTopArr[idx] - ColBotArr[idx]) + 1;
            tgt := BoxToPrice(ColBotArr[idx], BoxSize) + (boxesInCol * BoxSize * CountMultiplier);
          end
          else
          begin
            wCount := 0;
            for j := idx downto 0 do
            begin
              if (BoxToPrice(ColBotArr[j], BoxSize) <= brk + 1e-12) and
                 (BoxToPrice(ColTopArr[j], BoxSize) >= brk - 1e-12) then
                wCount := wCount + 1
              else
                break;
            end;
            tgt := brk + (wCount * BoxSize * CountMultiplier);
          end;

          TargetPriceArr[idx] := tgt;
        end;
      end;
    end
    else
    { Double-bottom SELL }
    if (ColTypeArr[idx] = -1) and (ColTypeArr[idx-2] = -1) then
    begin
      if ColBotArr[idx] <= ColBotArr[idx-2] - 1 then
      begin
        brk := BoxToPrice(ColBotArr[idx-2] - 1, BoxSize);
        SigTypeArr[idx] := -1;
        SigPriceArr[idx] := brk;

        if DrawCountTargets and (CountMethod <> 0) then
        begin
          if CountMethod = 1 then
          begin
            boxesInCol := (ColTopArr[idx] - ColBotArr[idx]) + 1;
            tgt := BoxToPrice(ColTopArr[idx], BoxSize) - (boxesInCol * BoxSize * CountMultiplier);
          end
          else
          begin
            wCount := 0;
            for j := idx downto 0 do
            begin
              if (BoxToPrice(ColBotArr[j], BoxSize) <= brk + 1e-12) and
                 (BoxToPrice(ColTopArr[j], BoxSize) >= brk - 1e-12) then
                wCount := wCount + 1
              else
                break;
            end;
            tgt := brk - (wCount * BoxSize * CountMultiplier);
          end;

          TargetPriceArr[idx] := tgt;
        end;
      end;
    end;
  end;

  { ===== Scale min/max bouwen ===== }
  scaleMin := priceMin - (ScalePadBoxes * BoxSize);
  scaleMax := priceMax + (ScalePadBoxes * BoxSize);

  if IncludeTargetsInScale and DrawCountTargets then
  begin
    for idx := 0 to nCols-1 do
      if (TargetPriceArr[idx] <> 0) then
      begin
        if TargetPriceArr[idx] < scaleMin then scaleMin := TargetPriceArr[idx] - BoxSize;
        if TargetPriceArr[idx] > scaleMax then scaleMax := TargetPriceArr[idx] + BoxSize;
      end;
  end;

  for i := 0 to BarCount-1 do
  begin
    sMinLine[i] := scaleMin;
    sMaxLine[i] := scaleMax;
  end;

  { ===== Rendering columns + signals + targets ===== }
  if AutoSwitchXO and (colsDraw > MaxColsForXO) then
    DrawXO := false;

  for idx := startCol to nCols-1 do
  begin
    if ColTypeArr[idx] = 0 then continue;

    colAdj := idx - startCol;
    barIdx := ColAdjToBarIdx(colAdj, colsDraw, BarCount, Index0IsCurrent);
    xDT := BarPosition[barIdx];

    y1 := BoxToPrice(ColBotArr[idx], BoxSize);
    y2 := BoxToPrice(ColTopArr[idx], BoxSize);

    if ColTypeArr[idx] = +1 then colClr := BullColumnColor else colClr := BearColumnColor;

    { Kolom tekenen }
    if not DrawXO then
    begin
      DrawSegDT(xDT, y1, xDT, y2, colClr, 2);
    end
    else
    begin
      if SymbolStepBoxes < 1 then SymbolStepBoxes := 1;

      if ColTypeArr[idx] = +1 then
      begin
        j := ColBotArr[idx];
        while j <= ColTopArr[idx] do
        begin
          DrawTextDT(xDT, BoxToPrice(j, BoxSize), 'X', BullColumnColor, TextFontSize);
          j := j + SymbolStepBoxes;
        end;
      end
      else
      begin
        j := ColTopArr[idx];
        while j >= ColBotArr[idx] do
        begin
          DrawTextDT(xDT, BoxToPrice(j, BoxSize), '0', BearColumnColor, TextFontSize);
          j := j - SymbolStepBoxes;
        end;
      end;
    end;

    { Signal marker + label }
    if DrawSignals and (SigTypeArr[idx] <> 0) then
    begin
      Case BuySellSymbDist of
        1 : FillUp := ' ';
        2 : FillUp := '  ';
        3 : FillUp := '   ';
        4 : FillUp := '    ';
        5 : FillUp := '     ';
      end;
    
      brk := SigPriceArr[idx];

      if SigTypeArr[idx] = +1 then
      begin
       // DrawSegDT(xDT, brk, xDT, brk + BoxSize*0.25, clAqua, 2);
        DrawTextDT(xDT, ClampRealToRange(brk, scaleMin, scaleMax), 'B '+ FillUp, BuySignalColor, TextFontSize);
      end
      else
      begin
       // DrawSegDT(xDT, brk, xDT, brk - BoxSize*0.25, clFuchsia, 2);
        DrawTextDT(xDT, ClampRealToRange(brk, scaleMin, scaleMax), 'S'+ FillUp, SellSignalColor, TextFontSize);
      end;
    end;

    { Count target: verticale lijn van breakout naar target + tekst (geclamped naar min/max) }
    if DrawCountTargets and (SigTypeArr[idx] <> 0) and (TargetPriceArr[idx] <> 0) then
    begin
      tgt := TargetPriceArr[idx];
      brk := SigPriceArr[idx];

      if SigTypeArr[idx] = +1 then colClr := BuyTargetColor else colClr := SellTargetColor;

      DrawSegDT(xDT, brk, xDT, tgt, colClr, TargetLineWidth);

      if ShowTargetText then
      begin
        if tgt > scaleMax then
        begin
          yText := scaleMax;
          txt := 'T^ ' + FormatFloat('0.0', tgt);
        end
        else if tgt < scaleMin then
        begin
          yText := scaleMin;
          txt := 'Tv ' + FormatFloat('0.0', tgt);
        end
        else
        begin
          yText := tgt;
          txt := 'T ' + FormatFloat('0.0', tgt);
        end;

        DrawTextDT(xDT, yText, txt, colClr, TextFontSize);
      end;
    end;
  end;

  { ==========================================================
    45° Trendlines (multiple parallel)
    - Bull support: +1 box per column
    - Bear resistance: -1 box per column
    - Breuk:
        Bull: O-bodem <= (lijn - 1 box)
        Bear: X-top   >= (lijn + 1 box)
      Indien BreakNeedsSignal=true:
        Bull-breuk telt alleen als er een SELL-signaal in die kolom is
        Bear-breuk telt alleen als er een BUY-signaal  in die kolom is
    ========================================================== }
  if Show45Lines then
  begin
    { ---------- Bullish support lines (blue) ---------- }
    if Show45Bull then
    begin
      lineStartCol := -1;
      for idx := startCol to nCols-1 do
        if ColTypeArr[idx] = -1 then
        begin
          lineStartCol := idx;
          lineY0 := BoxToPrice(ColBotArr[idx] - 1, BoxSize); { 1 box onder bodem }
          break;
        end;

      if lineStartCol >= 0 then
      begin
        lineCount := 0;
        cWalk := lineStartCol;

        while (cWalk <= nCols-1) do
        begin
          yLine := lineY0 + BoxSize * (cWalk - lineStartCol);

          breach := false;
          if (ColTypeArr[cWalk] = -1) then
            breach := (BoxToPrice(ColBotArr[cWalk], BoxSize) <= (yLine - BoxSize + eps));

          useSignalBreach := true;
          if BreakNeedsSignal then
            useSignalBreach := (SigTypeArr[cWalk] = -1); { SELL }

          if breach and useSignalBreach and (lineCount < (Max45LinesPerSide - 1)) then
          begin
            lineEndCol := cWalk;

            if lineEndCol > lineStartCol then
            begin
              lineYEnd := lineY0 + BoxSize * (lineEndCol - lineStartCol);

              colAdj := lineStartCol - startCol;
              barIdx := ColAdjToBarIdx(colAdj, colsDraw, BarCount, Index0IsCurrent);
              tStart := BarPosition[barIdx];

              colAdj := lineEndCol - startCol;
              barIdx := ColAdjToBarIdx(colAdj, colsDraw, BarCount, Index0IsCurrent);
              tEnd := BarPosition[barIdx];

              DrawSegDT(tStart, lineY0, tEnd, lineYEnd, BullTrendLineColor, Line45Width);
            end;

            { start nieuwe parallelle lijn vanaf breach-kolom }
            lineStartCol := cWalk;
            lineY0 := BoxToPrice(ColBotArr[cWalk] - 1, BoxSize);
            lineCount := lineCount + 1;
          end;

          cWalk := cWalk + 1;
        end;

        { laatste segment tot einde }
        lineEndCol := nCols - 1;
        if lineEndCol > lineStartCol then
        begin
          lineYEnd := lineY0 + BoxSize * (lineEndCol - lineStartCol);

          colAdj := lineStartCol - startCol;
          barIdx := ColAdjToBarIdx(colAdj, colsDraw, BarCount, Index0IsCurrent);
          tStart := BarPosition[barIdx];

          colAdj := lineEndCol - startCol;
          barIdx := ColAdjToBarIdx(colAdj, colsDraw, BarCount, Index0IsCurrent);
          tEnd := BarPosition[barIdx];

          DrawSegDT(tStart, lineY0, tEnd, lineYEnd, BullTrendLineColor, Line45Width);
        end;
      end;
    end;

    { ---------- Bearish resistance lines (red) ---------- }
    if Show45Bear then
    begin
      lineStartCol := -1;
      for idx := startCol to nCols-1 do
        if ColTypeArr[idx] = +1 then
        begin
          lineStartCol := idx;
          lineY0 := BoxToPrice(ColTopArr[idx] + 1, BoxSize); { 1 box boven top }
          break;
        end;

      if lineStartCol >= 0 then
      begin
        lineCount := 0;
        cWalk := lineStartCol;

        while (cWalk <= nCols-1) do
        begin
          yLine := lineY0 - BoxSize * (cWalk - lineStartCol);

          breach := false;
          if (ColTypeArr[cWalk] = +1) then
            breach := (BoxToPrice(ColTopArr[cWalk], BoxSize) >= (yLine + BoxSize - eps));

          useSignalBreach := true;
          if BreakNeedsSignal then
            useSignalBreach := (SigTypeArr[cWalk] = +1); { BUY }

          if breach and useSignalBreach and (lineCount < (Max45LinesPerSide - 1)) then
          begin
            lineEndCol := cWalk;

            if lineEndCol > lineStartCol then
            begin
              lineYEnd := lineY0 - BoxSize * (lineEndCol - lineStartCol);

              colAdj := lineStartCol - startCol;
              barIdx := ColAdjToBarIdx(colAdj, colsDraw, BarCount, Index0IsCurrent);
              tStart := BarPosition[barIdx];

              colAdj := lineEndCol - startCol;
              barIdx := ColAdjToBarIdx(colAdj, colsDraw, BarCount, Index0IsCurrent);
              tEnd := BarPosition[barIdx];

              DrawSegDT(tStart, lineY0, tEnd, lineYEnd, BearTrendLineColor, Line45Width);
            end;

            { start nieuwe parallelle lijn vanaf breach-kolom }
            lineStartCol := cWalk;
            lineY0 := BoxToPrice(ColTopArr[cWalk] + 1, BoxSize);
            lineCount := lineCount + 1;
          end;

          cWalk := cWalk + 1;
        end;

        { laatste segment tot einde }
        lineEndCol := nCols - 1;
        if lineEndCol > lineStartCol then
        begin
          lineYEnd := lineY0 - BoxSize * (lineEndCol - lineStartCol);

          colAdj := lineStartCol - startCol;
          barIdx := ColAdjToBarIdx(colAdj, colsDraw, BarCount, Index0IsCurrent);
          tStart := BarPosition[barIdx];

          colAdj := lineEndCol - startCol;
          barIdx := ColAdjToBarIdx(colAdj, colsDraw, BarCount, Index0IsCurrent);
          tEnd := BarPosition[barIdx];

          DrawSegDT(tStart, lineY0, tEnd, lineYEnd, BearTrendLineColor, Line45Width);
        end;
      end;
    end;

  end;

end.
.
Afbeelding
.
Laatst gewijzigd door Janus op di jan 13, 2026 5:46 pm, 3 keer totaal gewijzigd.
Vriendelijke groet,
JanS ;)
Janus
Berichten: 1514
Lid geworden op: wo jan 30, 2008 2:07 am
Contacteer:

Re: Point & Figure grafieken

Bericht door Janus »

Hieronder een afbeelding, met ingezoomde grafiek en koersdoelen, waarbij de Y-as (via een vinkje 'TargetInScale)) kan worden ingesteld zodat deze de koersdoelen op werkelijke waarde tekent.
.
Afbeelding
.
De B en de S geeft het moment weer waarop een eventueel Buy of Sell signaal volgt.
U kan dit nog niet gebruiken als een koop of verkoop signaal om de effectiviteit ervan te testen, dat komt later (er komt nog wat meer bij kijken namelijk).

En nog een afbeelding met de automatische trendlijnen er in weergegeven.
.
Afbeelding

En voordat u denkt: 'de onderste blauwe lijn 'klopt niet', moet u eerst even de help tekst doorlezen.

Er volgen nog diverse uitbreidingen op deze P&F code zoals een procentuele schaal en en de 'one step back' enzovoorts.

Speel even met de code en meldt 'problemen' a.u.b..

Ik plaats onder deze post nog even een post met een uitgebreidere help tekst dan de tekst die wordt meegeleverd in de TA-script code.
Vriendelijke groet,
JanS ;)
Janus
Berichten: 1514
Lid geworden op: wo jan 30, 2008 2:07 am
Contacteer:

Re: Point & Figure grafieken

Bericht door Janus »

Uitgebreidere help tekst:
*
Point & Figure met signalen, targets en 45° trendlijnen
Deze indicator tekent een Point & Figure (P&F)-grafiek bovenop de koersgrafiek; ofwel: in het betreffende venster).
De P&F wordt opgebouwd uit kolommen met X (stijging) en 0 (daling) met een vaste BoxSize en een ReversalBoxes-omkeerregel.
Optioneel worden Double-Top / Double-Bottom signalen, koersdoelen (targets) en 45° trendlijnen weergegeven.
Basisinstellingen (P&F constructie)
BoxSize
Grootte van één box in koerspunten. Bij AEX bijvoorbeeld vaak 1, 2, 5 of 10. Een grotere BoxSize geeft een grovere (rustigere) P&F.
ReversalBoxes
Aantal boxes dat de koers minimaal tegen de trend in moet bewegen om een nieuwe kolom te starten.
Voorbeeld: bij 3-box reversal moet de koers minimaal 3 boxes draaien voordat er van X naar 0 (of omgekeerd) wordt gewisseld.
Use High/Low (anders Close-only)
• True: P&F wordt opgebouwd met High/Low per bar (meestal “klassiek”).
• False: P&F wordt opgebouwd met alleen Close (kan “gaten” geven; minder gevoelig).
Max. Colums to Draw
Beperkt het aantal P&F-kolommen dat wordt getekend (van de meest recente terug). Hiermee voorkom je te volle schermen.
________________________________________
Weergave: X/0 of streepjes
Draw X / 0
• True: toont X en 0-symbolen per box.
• False: tekent per kolom één verticale lijn (sneller en minder druk).
Auto-switch to bars when crowded
Als er meer kolommen worden getekend dan MaxColsForXO, schakelt de indicator automatisch over naar streepjes i.p.v. X/0 (leesbaarheid).
MaxColsForXO
Drempelwaarde voor de autoswitch.
Bijv. 80: tot 80 kolommen X/0, daarboven streepjes.
SymbolStepBoxes (1=elk box)
Tekent niet in elke box een X/0, maar met stapgrootte:
• 1 = elke box een symbool
• 2 = om de box, enz.
Handig als X/0 te dicht op elkaar komen.
________________________________________
Signalen (Double-Top / Double-Bottom)
Draw DoubleTop/Bottom signals
Zet de signalen aan/uit.
• Koop (BUY) bij Double-Top breakout: een X-kolom breekt boven een eerdere X-top uit.
• Verkoop (SELL) bij Double-Bottom breakdown: een 0-kolom breekt onder een eerdere 0-bodem uit.
B-S-Column distance
Extra “spatie” (afstand) om de B/S-letter in de kolom iets beter leesbaar te maken.
Hogere waarde = meer naar rechts “uitgevuld”.
BuySignal Color / SellSignal Color
Kleuren voor de B (buy) en S (sell) markering.
________________________________________
Targets (Vertical / Horizontal Count)
CountMethod
Kies hoe koersdoelen worden berekend:
• 0 = None : geen targets
• 1 = Vertical : vertical count target (boxen in de breakout-kolom tellen)
• 2 = Horizontal (simple) : eenvoudige horizontal count (aantal kolommen in de basis “meetellen” rond het breakout-niveau)
CountMultiplier
Vermenigvuldigingsfactor voor targets. Vaak gelijk aan ReversalBoxes (klassieke benadering), maar je kunt ermee experimenteren.
Draw Count Targets
Tekent targets aan/uit. Targets worden weergegeven als een verticale lijn vanaf het signaalniveau naar het targetniveau.
TargetLineWidth
Dikte van de target-lijn.
ShowTargetText
Toont het targetgetal als tekst.
Als het target buiten de schaal valt, wordt de tekst op ScaleMin/ScaleMax gezet met markering:
• T^ = target ligt boven beeld
• Tv = target ligt onder beeld
BuyTarget Color / SellTarget Color
Kleuren voor target-lijnen en targettekst.
________________________________________
Schaal (Y-as) en leesbaarheid
Voor de beste ‘leesbaarheid’ regelt de indicator de Y-as waarden.
ScaleLookbackBars (0=all)
Bepaalt over hoeveel koersbars de schaal wordt berekend:
• 0 = volledige dataset in beeld
• 250 = schaal over de laatste 250 bars
ScalePadBoxes
Extra marge boven/onder de schaal in aantal boxes.
Handig om targets of labels niet tegen de rand te laten plakken.
IncludeTargetsInScale
• True: schaal wordt ook aangepast zodat targets meestal binnen beeld vallen (kan schaal “oprekken”).
• False: schaal volgt vooral de koersrange.
________________________________________
45° Trendlijnen (Du Plessis-stijl)
Show 45deg Trendlines
Hoofdschakelaar voor 45°-lijnen.
45deg Bull Support
Tekent stijgende 45°-supportlijnen (bullish), parallel na “breuk”.
45deg Bear Resistance
Tekent dalende 45°-resistancelijnen (bearish), parallel na “breuk”.
Trendline break needs valid signal
Du Plessis-regel: een trendlijn is pas écht ongeldig als na de penetratie een geldig signaal ontstaat.
• Bull-support: breuk telt pas bij een SELL signaal
• Bear-resistance: breuk telt pas bij een BUY signaal
Max 45deg lines per side
Maximaal aantal parallelle 45°-lijnen dat per richting getekend wordt.
45deg Line Width
Dikte van de 45°-lijnen.
BullTrendLine Color / BearTrendLine Color
Kleuren van de 45° bull/bear trendlijnen.
________________________________________
Kleuren en achtergrond
Background Color
Achtergrondkleur van het P&F vlak.
BullColumn Color X / BearColumn Color 0
Kleur van de X- en 0-kolommen.
________________________________________
Tip voor starten
Een praktische start voor AEX (dag):
• BoxSize = 5
• ReversalBoxes = 3
• Draw X/0 = True (en Auto-switch aan)
• CountMethod = 1 (Vertical) met CountMultiplier = 3
• Show 45deg Trendlines = True
Vriendelijke groet,
JanS ;)
Bakstenen
Berichten: 992
Lid geworden op: zo jul 19, 2015 7:51 pm

Re: Point & Figure grafieken

Bericht door Bakstenen »

Zo dat is een hoop werk Jan, ga het eens rustig lezen.
bedankt
Bakstenen
Berichten: 992
Lid geworden op: zo jul 19, 2015 7:51 pm

Re: Point & Figure grafieken

Bericht door Bakstenen »

Jan,
ik krijg niet de PF in het onderste venster, zie bijlage
knipsel.jpg
Janus
Berichten: 1514
Lid geworden op: wo jan 30, 2008 2:07 am
Contacteer:

Re: Point & Figure grafieken

Bericht door Janus »

** De code is gewijzigd, je kan nu gewoon een grafiek venster openen, en dan daarin de P&F indicator kiezen, waarna deze in een nieuw venster wordt geopend. **
.
Laatst gewijzigd door Janus op di jan 13, 2026 7:15 pm, 2 keer totaal gewijzigd.
Vriendelijke groet,
JanS ;)
Bakstenen
Berichten: 992
Lid geworden op: zo jul 19, 2015 7:51 pm

Re: Point & Figure grafieken

Bericht door Bakstenen »

Blijft hetzelfde
Janus
Berichten: 1514
Lid geworden op: wo jan 30, 2008 2:07 am
Contacteer:

Re: Point & Figure grafieken

Bericht door Janus »

Beste heer Bakstenen, ik heb de code die ik had geplaatst iets gewijzigd. Je kan nu gewoon een grafiek venster openen, en dan direct de code kiezen. Die wordt dan direct in een nieuw venter eronder geplaatst. Je moet dus wel even de aangepaste code installeren
Laatst gewijzigd door Janus op di jan 13, 2026 5:43 pm, 1 keer totaal gewijzigd.
Vriendelijke groet,
JanS ;)
Bakstenen
Berichten: 992
Lid geworden op: zo jul 19, 2015 7:51 pm

Re: Point & Figure grafieken

Bericht door Bakstenen »

gelukt, bedankt
Plaats reactie