# NEOTICKER DATA BEGIN ScriptType=Indicator Description=Point n Figure Managed Series Name=PointNFigureManagedSeries Language=DelphiScript Links=1 MinBars=0 TimerInterval=100 EarlyBinding=0 MetaStyle=Candle ValueRange=Same as Source Placement=Smart Multiplot_num_plots=4 Multiplot_color_0=33619712 Multiplot_style_0=Dot Multiplot_width_0=4 Multiplot_enabled_0=1 Multiplot_name_0=Bullish Multiplot_breakstyle_0=0 Multiplot_color_1=33619967 Multiplot_style_1=Dot Multiplot_width_1=4 Multiplot_enabled_1=1 Multiplot_name_1=Bearish Multiplot_breakstyle_1=0 Multiplot_color_2=255 Multiplot_style_2=Line Multiplot_width_2=1 Multiplot_enabled_2=1 Multiplot_breakstyle_2=0 Multiplot_color_3=255 Multiplot_style_3=Line Multiplot_width_3=1 Multiplot_enabled_3=1 Multiplot_breakstyle_3=0 UpdateByTick=0 TradingSystemUI=0 PrimaryLinkOnly=0 NotifyOnRemoval=0 Param_count=3 Param_name_0=Box Size Param_inuse_0=1 Param_type_0=real Param_default_0=0.5 Param_name_1=Reversal Param_inuse_1=1 Param_type_1=integer.gt.0 Param_default_1=3 Param_name_2=Report Bars Param_inuse_2=1 Param_type_2=string Param_default_2=Y|N Explanation_Lines=0 # NEOTICKER DATA END // Point and Figure Managed Series // written by Lawrence Chan // Copyright (C) 2006 TickQuest Inc. // All rights reserved // a general tool for dumping a series to the report window procedure report_series (aseries); var i : integer; begin for i := aseries.barsnum [0] downto 0 do report.addline ('', NTLib.format ( '%8d %6d %8.2f %8.2f %8.2f %8.2f %3.0f', [NTLib.date2int (aseries.date [i]), NTLib.time2int (aseries.time [i]), aseries.open [i], aseries.high [i], aseries.low [i], aseries.close [i], aseries.pf [i] ])); end; // main indicator function function PointNFigureManagedSeries : double; var new_bar, update_bar, new_pf : boolean; box_size, reversal_range, new_box_high, new_box_low : double; pfseries; i : integer; begin if not data1.valid [0] then begin itself.successall := false; exit; end; // generating embedded point and figure series box_size := param1.real; reversal_range := box_size * param2.int; pfseries := itself.managedseries ('pf'); // on completion of first recalc, generate price list // if the user choose to if data1.islastbar and (pheap.size <= 0) then begin pheap.allocate (1); if param3.str = 'Y' then report_series (pfseries); end; // point and figure bar generation logic new_bar := false; update_bar := false; if pfseries = nil then // first bar begin new_bar := true; new_pf := true; new_box_high := NTLib.round (data1.value [0] / box_size) * box_size; if new_box_high < data1.value [0] then new_box_high := new_box_high + box_size; new_box_low := NTLib.round (data1.value [0] / box_size) * box_size; if new_box_low > data1.value [0] then new_box_low := new_box_low - box_size; end else if pfseries.pf [0] > 0 then // current pf bar is up begin if data1.value [0] > pfseries.high [0] then // extend the current up bar begin update_bar := true; new_box_high := NTLib.round (data1.value [0] / box_size) * box_size; if new_box_high < data1.value [0] then new_box_high := new_box_high + box_size; end else if data1.value [0] < (pfseries.high [0] - reversal_range) then // reversal down begin new_bar := true; new_pf := false; new_box_high := pfseries.high [0] - box_size; new_box_low := NTLib.round (data1.value [0] / box_size) * box_size; if new_box_low > data1.value [0] then new_box_low := new_box_low - box_size; end; end else // if pfseries.pf [0] < 0 then begin if data1.value [0] < pfseries.low [0] then // extend the current down bar begin update_bar := true; new_box_low := NTLib.round (data1.value [0] / box_size) * box_size; if new_box_low > data1.value [0] then new_box_low := new_box_low - box_size; end else if data1.value [0] > (pfseries.low [0] + reversal_range) then // reversal up begin new_bar := true; new_pf := true; new_box_high := NTLib.round (data1.value [0] / box_size) * box_size; if new_box_high < data1.value [0] then new_box_high := new_box_high + box_size; new_box_low := pfseries.low [0] + box_size; end; end; if new_bar then begin // set open of bar itself.setmanagedseries ( 'pf', ppTick, 1, data1.value [0], 0, 0, new_pf, true, true); // set high of bar itself.setmanagedseries ( 'pf', ppTick, 1, new_box_high, 0, 0, new_pf, true, false); // set low of bar itself.setmanagedseries ( 'pf', ppTick, 1, new_box_low, 0, 0, new_pf, true, false); // set close of bar itself.setmanagedseries ( 'pf', ppTick, 1, data1.value [0], 1, data1.volume [0], new_pf, true, false); end else if update_bar then begin if pfseries.pf [0] > 0 then // current pf bar is up begin // set high of bar itself.setmanagedseries ( 'pf', ppTick, 1, new_box_high, 0, 0, true, true, false); // set close of bar itself.setmanagedseries ( 'pf', ppTick, 1, data1.value [0], 1, data1.volume [0], true, true, false); end else begin // set low of bar itself.setmanagedseries ( 'pf', ppTick, 1, new_box_low, 0, 0, false, true, false); // set close of bar itself.setmanagedseries ( 'pf', ppTick, 1, data1.value [0], 1, data1.volume [0], false, true, false); end; end else begin // set close of bar itself.setmanagedseries ( 'pf', ppTick, 1, data1.value [0], 1, data1.volume [0], pfseries.pf [0] > 0, true, false); end; // to access the series, assign it to a variable and then you can use it // just like any other series pfseries := itself.managedseries ('pf'); if pfseries = nil then begin itself.successall := false; exit; end; // output completed bars whenever a new bar is generated if new_bar and (pfseries.barsnum [0] > 0) then begin itself.plot [1] := pfseries.open [1]; itself.plot [2] := pfseries.high [1]; itself.plot [3] := pfseries.low [1]; itself.plot [4] := pfseries.close [1]; end else begin itself.successall := false; end; end;