RibbonsPlotter indicator with Multicharts. Please help.

Studies that have been contributed to the community by other users. If you’ve got something useful to share, that’s great!
FHTrader
Posts: 38
Joined: 24 Feb 2010

RibbonsPlotter indicator with Multicharts. Please help.

Postby FHTrader » 13 Mar 2010

Hi,

I have this RibbonsPlotter indicator from TS forum:

TS.com/Discussions/Topic.aspx?Topic_ID=89978&SearchTerm=RibbonsPlotter%20&txtExactMatch=&Page=1

I never had any problem using it with TS. But with Multicharts, it has this Error of Floating-point invalid operation.

Can someone please help? Thanks.

Code: Select all

{
Indicator:      _RibbonsPlotter

Description:    This Indictor plots various types of ribbons (multiple bands of deviation functions)
                around a centerline reference function.

Provided By:    Mark J. Krisburg (MarkSanDiego)

Updated:        02/18/07    original version
                09/14/08    fixed offset
                01/03/09    lower band function formula error correction
                01/04/09    future projections added (FutureOffset = 1 or 2)
                04/30/09    clean up and tighten code
                05/29/09    add display of input parameters on chart
                07/08/09    _BarsDisplayed function modified to minimize increase in MaxBarsBack
                            cause by back referencing to print chart labels after LastBarOnChart
                            reached.
                07/10/09    WVAP added as to centerline functions   
               
************************************************************************************** 
                { Reference Function (Center line) May be: }       
                0-Zero axis
                1-AMA (Arithmetic Average)
                2-EMA (Exponential Moving Average
                3-LR (Linear Regression)
                4-Adaptive Moving Avg (Kaufman - KAMA)
                5-T3 Triple Exponential Moving Average
                6-JMA Juric Moving Average or
                7-WVAP
                8-Fixed Value

                { Deviation Function (Band or Ribbons) may be: }
                1-Standard Deviation (Bollinger Bands)
                2-Standard Error
                3-ATR (Average True Range - Keltner Bands)
                4 JMA True Range (ATR using Jurik Moving Avg)
                5-Pct (Percentage)
                6-Points
**************************************************************************************
}
                   
[LegacyColorValue = true];

Inputs:     
    Price(low),
    Smooth(0),

    UpperBandsRef(TypicalPrice),
    LowerBandsRef(TypicalPrice),
    Offset(0),

    RefID(3),
    AMALength(15),                  { arithmetic moving average length }
    EMALength(15),                  { exponential moving average length }
    LRLength(15),                   { linear regression function length }
    LRTgtBar(0),                    { linear regression function target bar }
    KAMA_EffRatioLen(7),            { Kaufman adaptive moving average parameters }
    KAMA_FastLength(2),             { Kaufman adaptive moving average parameters }
    KAMA_SlowLength(25),            { Kaufman adaptive moving average parameters }
    T3Length(20),
    JMALength(20),
    JMAPhase(0),
    VWAP("No Param RefID = 7"),
    RefValue(0),

    DevID(1),                        { deviation function identifier }
    StdDevLength(15),                { standard deviation length }
    StdErrLength(15),                { standard error length }
    ATRLength(14),                   { average true range length }
    JATRLength(14),                  { percentage }
    Percent(1),                         
    Pts(1),

    NBands(3),                       { maximum 8 }
    StartMult(1),
    Increment(1),
    AddMinus(0),
    RoundToTradable(False),
   
    PlotWidth(0),
    ShowCenterLine(true),
    DisplayParameters(true),         { display chart parameters }
    CLParamColor(yellow),            { center line parameters display color }
    DevParamColor(cyan),             { deviation parameters display color }
    CLVertPct(8),                    { vertical position in chart range percent for center line parameter display }
    DevVertPct(3),                   { vertical position in chart range percent for deviation parameter display }
    CLHorizPct(50),                  { horizontal position in percent for center line parameter display
                                       [leftmost = zero %, rightmost = 100%] }
    DevHorizPct(50);                 { horizontal position in percent for deviation parameter display
                                       [leftmost = zero %, rightmost = 100%] }

Arrays:
    UpperBand[9](0),
    LowerBand[9](0),
    RefParam[4](0),                  { reference function (center line) parameters }
    DevParam[4](0);                  { deviation function (bands or ribbons) parameters }

Variables:     
    UpperCL(0),
    LowerCL(0),
   
    { chart display parameters }
    intrabarpersist string Text1("Center Line:     "),       
    intrabarpersist string Text2("    Deviation:     "),
    intrabarpersist TextVertPct1(CLVertPct),
    intrabarpersist TextVertPct2(DevVertPct),
    intrabarpersist TextHorizPct1(CLHorizPct),
    intrabarpersist TextHorizPct2(DevHorizPct),
    intrabarpersist TextVert1(0),
    intrabarpersist TextVert2(0),
    intrabarpersist int TextOffset1(0),
    intrabarpersist int TextOffset2(0),
    intrabarpersist DisplayHigh(0),
    intrabarpersist DisplayLow(0),
    intrabarpersist DisplayRange(0),
    intrabarpersist BarsDisplayed(0),
    intrabarpersist TextID1(0),
    intrabarpersist TextID2(0),
    intrabarpersist RangePctAtOffset(0),
    intrabarpersist TextLength1(0),
    intrabarpersist TextLength2(0),
    intrabarpersist TextMaxLength(0);


{ pack reference and deviation function parameters into arrays }

Once begin
       
    { initialize display parameters text strings }
           

    { Reference function parameters }
    RefParam[0] = RefID;
    switch RefID begin
        Case 0:
            RefParam[1] = 0;
            Text1 = Text1 & "Zero axis";
        Case 1:
            RefParam[1] = AMALength;
            Text1 = Text1 & "AMA " & NumToStr(AMALength, 0);
        Case 2:
            RefParam[1] = EMALength;
            Text1 = Text1 & "EMA " & NumToStr(EMALength, 1);               
        Case 3:
            RefParam[1] = LRLength;
            RefParam[2] = LRTgtBar;
            Text1 = Text1 & "LinReg " & NumToStr(LRLength, 0)
                & "  Offset " & NumToStr(Offset,0) & "  TgtBar " & NumToStr(LRTgtBar, 0);
        Case 4:
            RefParam[1] = KAMA_EffRatioLen;
            RefParam[2] = KAMA_FastLength;
            RefParam[3] = KAMA_SlowLength;
            Text1 = Text1 & "KAMA " & NumToStr(KAMA_EffRatioLen, 1)
                & ", " & NumToStr(KAMA_FastLength, 1) & ", " & NumToStr(KAMA_SlowLength, 1);
        Case 5:
            RefParam[1] = T3Length;
            Text1 = Text1 & "T3  " & NumToStr(T3Length, 0);
        Case 6:
            RefParam[1] = JMALength;
            RefParam[2] = JMAPhase;
            Text1 = Text1 & "JMA " & NumToStr(JMALength, 0) & "  Phase " & NumToStr(JMAPhase, 0);
        Case 7:
            Text1 = Text1 & "VWAP";   
               
        Case 8:
            RefParam[1] = RefValue;
            Text1 = Text1 & "Value = " & NumToStr(RefValue, 1);
    end;

    { Deviation function parameters }
    DevParam[0] = DevID;
    switch DevID begin
        Case 1:
            DevParam[1] = StdDevLength;
            Text2 = Text2 & "Std Dev " & NumToStr(StdDevLength, 0);
        Case 2:
            DevParam[1] = StdErrLength;
            Text2 = Text2 & "Std Err " & NumToStr(StdErrLength, 0);
        Case 3:
            DevParam[1] = ATRLength;
            Text2 = Text2 & "ATR " & NumToStr(ATRLength, 0);
        Case 4:
            DevParam[1] = JATRLength;
            Text2 = Text2 & "JURIC ATR " & NumToStr(JATRLength, 0);
        Case 5:
            DevParam[1] = Percent;
            Text2 = Text2 & "Percent " & NumToStr(Percent, 1);
        Case 6:
            DevParam[1] = Pts;
            Text2 = Text2 & "Points " & NumToStr(Pts, 2);
    end;


    TextID1 = Text_New(0, 0, 0, Text1);
    TextID2 = Text_New(0, 0, 0, Text2);
    value1 = Text_SetColor(TextID1, CLParamColor);
    value2 = Text_SetColor(TextID2, DevParamColor);

    TextLength1 = StrLen(Text1);
    TextLength2 = StrLen(Text2);
    TextMaxLength = MaxList(TextLength1, TextLength2);

end;
   


    Value1 = _RibbonsCalc(UpperBandsRef[Offset], LowerBandsRef[Offset], RefParam, DevParam,
                NBands, StartMult, Increment, AddMinus, RoundToTradable, UpperBand, LowerBand);

      { PLOTTING }
    If NBands >= 1 Then Begin
        Plot8(UpperBand[1],"Hi-1", default, default, PlotWidth);
        Plot10(LowerBand[1],"Lo-1", default, default, PlotWidth);
               
        If NBands >=2 Then Begin
            Plot7(UpperBand[2],"Hi-2", default, default, PlotWidth);
            Plot11(LowerBand[2],"Lo-2", default, default, PlotWidth);
               
            If NBands >=3 Then Begin
                Plot6(UpperBand[3],"Hi-3", default, default, PlotWidth);
                Plot12(LowerBand[3],"Lo-3", default, default, PlotWidth);
 
                If NBands >= 4 Then Begin
                    Plot5(UpperBand[4],"Hi-4", default, default, PlotWidth);
                    Plot13(LowerBand[4],"Lo-4", default, default, PlotWidth);

                    If NBands >= 5 Then Begin
                        Plot4(UpperBand[5],"Hi-5", default, default, PlotWidth);
                        Plot14(LowerBand[5],"Lo-5", default, default, PlotWidth);
                                             
                        If NBands >=6 Then Begin
                            Plot3(UpperBand[6], "Hi-6", default, default, PlotWidth);
                            Plot15(LowerBand[6],"Lo-6", default, default, PlotWidth);
                                           
                            If NBands >=7 Then Begin
                                Plot2(UpperBand[7],"Hi-7", default, default, PlotWidth);
                                Plot16(LowerBand[7],"Lo-7", default, default, PlotWidth);
                       
                                If NBands >=8 Then Begin
                                    Plot1(UpperBand[8],"Hi-8", default, default, PlotWidth);
                                    Plot17(LowerBand[8],"Lo-8", default, default, PlotWidth);
                                End;
                            End;
                        End;
                    End;
                End;
            End;
        End;   
    End;

    if ShowCenterLine then begin
        Plot9(UpperBand[0] + AddMinus,"URef", default, default, PlotWidth);
        If LowerBand[0] <> UpperBand[0] Then Plot18(LowerBand[0] + AddMinus,"LRef", default, default, PlotWidth);
    end;


    if Smooth > 0 then Plot21(Average(Price, Smooth), "Smooth Price");
    //if Smooth > 0 then Plot21(JRC.JMA.2k(Price, Smooth,0), "Smooth Price");
   

    { chart label section }
    { adding this section causes ribbon plotter to delay plotting for first 200 bars }
    { may wish to comment out this section if using ribbon plotter for strategy testing }
    { since almost 200 more bars of data will be available to analyze }         

    BarsDisplayed = _BarsDisplayed;

    if _LastBarOnChart then begin
       
        if DisplayParameters then begin

            switch RefID begin
                case 0, 7:
                    value1 = _DisplayRangeAll( DisplayHigh, DisplayLow, DisplayRange );

                default:
                    DisplayHigh = Highest(MaxList(UpperBand[NBands], High), BarsDisplayed);
                    DisplayLow = Lowest(MinList(LowerBand[NBands], Low), BarsDisplayed);
                    DisplayRange = DisplayHigh - DisplayLow;
            end;
           
            TextOffset1 = BarsDisplayed * (1 - TextHorizPct1 / 100) + TextMaxLength/2;
            TextOffset2 = BarsDisplayed * (1 - TextHorizPct2 / 100) + TextMaxLength/2;

            { determine range percent of price at middle of text string }
            RangePctAtOffset = (Close[(TextOffset1 + TextOffset2 - TextMaxLength)/2] - DisplayLow) / DisplayRange; 

            if RangePctAtOffset > 0.50 then begin
                TextVert1 = DisplayLow + DisplayRange * TextVertPct1 / 100;
                TextVert2 = DisplayLow + DisplayRange * TextVertPct2 / 100;
            end else begin
                TextVert1 = DisplayHigh - DisplayRange * TextVertPct2 / 100;
                TextVert2 = DisplayHigh - DisplayRange * TextVertPct1 / 100;
            end;

            value3 = Text_SetLocation(TextID1, Date[TextOffset1], Time[TextOffset1], TextVert1);
            value4 = Text_SetLocation(TextID2, Date[TextOffset2], Time[TextOffset2], TextVert2);
        end;   
    end;
{}
   
// debug:
//print(_DateTimeSymbol,TextID1,TextID2,TextOffset1,TextOffset2,DisplayLow,DisplayHigh,DisplayRange,TextVert1,TextVert2);


Code: Select all

{
Function:       _RibbonsCalc

Purpose:        This function calculates a series of bands (ribbons) displaced from a
                user specified centerline function.

                The band values are loaded into arrays UpperBand and LowerBand.
                The zero index item (ex. UpperBand[0]) represents the center line value.

Author:         MarkSanDiego

Updated:        09/08/08    original version derived from _RibbonsPlotter indicator
                01/30/09    prevent Standard Deviation function FXParam from being < 1
                05/29/09    clean up and stream line code


CenterLine:     May be:
                0 - Zero axis
                1 - AMA (Arithmetic Average)
                2 - EMA (Exponential Moving Average
                3 - LR (Linear Regression)
                4 - Adaptive Moving Avg (Kaufman - KAMA)
                5 - T3 Triple Exponential Moving Average
                6 - JMA Juric Moving Average or
                7 - Fixed Value

Band Function:  May be:
                1 - Standard Deviation (Bollinger Bands),
                2 - Standard Error (Anderson Bands )
                3 - Average True Range - ATR (Keltner Bands)
                4 - Jurik Average True Range (ATR using Jurik Moving Avg)
                5 - Percentage
                6 - Points

}
{

Usage:

Inputs:     
    Price(low),
    Smooth(0),

    UpperBandsRef(TypicalPrice),
    LowerBandsRef(TypicalPrice),

    RefID(3),
    AMALength(15),                  { arithmetic moving average length }
    EMALength(15),                  { exponential moving average length }
    LRLength(15),                   { linear regression function length }
    LRTgtBar(0),                    { linear regression function target bar }
    KAMA_EffRatioLen(7),            { Kaufman adaptive moving average parameters }
    KAMA_FastLength(2),             { Kaufman adaptive moving average parameters }
    KAMA_SlowLength(25),            { Kaufman adaptive moving average parameters }
    T3Length(20),
    JMALength(20),
    JMAPhase(0),
    RefValue(0),

    DevID(5),                       { deviation function identifier }
    StdDevLength(15),               { standard deviation length }
    StdErrLength(15),               { standard error length }
    ATRLength(14),                  { average true range length }
    JATRLength(14),                 { percentage }
    Percent(1),                         
    Pts(1),

    NBands(2),                      { maximum 8 }
    StartMult(1),
    Increment(1),
    AddMinus(0),
    RoundToTradable(False),
   
    PlotWidth(0),
    ShowCenterLine(true);

Arrays:
    UpperBand[9](0),                { array containing band values.  UpperBand[0] is the center line value }
    LowerBand[9](0),                { array containing band values.  UpperBand[0] is the center line value }
    RefParam[4](0),                 { reference function (center line) parameters }
    DevParam[4](0);                 { deviation function (bands or ribbons) parameters }

Variables: 
    UpperCL(0),
    LowerCL(0); 


        Value1 = _RibbonsCalc(UpperBandsRef, LowerBandsRef, RefParam, DevParam,
            NBands, StartMult, Increment, AddMinus, RoundToTradable, UpperBand, LowerBand);

}


Inputs:     
    UpperBandsRef(NumericSeries),
    LowerBandsRef(NumericSeries),

    RefParam[xx](NumericArrayRef),
    DevParam[yy](NumericArrayRef),

    NBands(NumericSimple),
    StartMult(NumericSimple),
    Increment(NumericSimple),
    AddMinus(NumericSimple),
    RoundToTradable(TrueFalseSimple),

{ Arrays: }
    UpperBand[tt](NumericArrayRef),
    LowerBand[uu](NumericArrayRef);

Variables: 
    intrabarpersist RefID(0),           { reference function ID }
    R1(0),                              { reference function parameters }
    R2(0),
    R3(0),
    R4(0),
    DevID(0),                           { deviation function ID }
    D1(0),                              { deviation function paramaters }
    D1b(0),                             { special handling required for standard dev and standard error functions }             
    D2(0),
    D3(0),
    D4(0),

    n(0),
    StartBar(0),
    intrabarpersist UpperFX(0),
    intrabarpersist LowerFX(0),
    intrabarpersist UpperCL(0),
    intrabarpersist LowerCL(0); 


{ unpack static reference and deviation function parameters }
       
once begin

    RefID = RefParam[0];
    R1 = RefParam[1];
    R2 = RefParam[2];
    R3 = RefParam[3];
    R4 = RefParam[4];

    DevID = DevParam[0];
    D1 = DevParam[1];
    D1b = MaxList(2, D1);               { special handling required for standard dev and standard error functions }
    D2 = DevParam[2];
    D3 = DevParam[3];
    D4 = DevParam[4];

end;
   
{ ESTABLISH CENTERLINE }

switch RefID begin
    Case 0:
        UpperCL = 0;
    case 1:
        UpperCL = AverageFC(UpperBandsRef, R1);
    case 2:
        UpperCL = XAverage(UpperBandsRef, R1);
    case 3:
        UpperCL = LinearRegValueFC(UpperBandsRef, R1, R2);
    case 4:
        UpperCL = AdaptiveMovAvg(UpperBandsRef,  R1, R2, R3);
    case 5:
        UpperCL = T3Average.Series(UpperBandsRef, R1);

  { {disable if Juric moving average not installed }
    case 6:
        UpperCL = JRC.JMA.2k(UpperBandsRef, R1, R2);}

   case 7:
        UpperCL = R1;
end;
   

if LowerBandsRef = UpperBandsRef  then begin
   
    LowerCL = UpperCL;

end else begin

    switch RefID begin
        Case 0:
            LowerCL = 0;
        case 1:
            LowerCL = AverageFC(LowerBandsRef, R1);
        case 2:
            LowerCL = XAverage(LowerBandsRef, R1);
        case 3:
            LowerCL = LinearRegValueFC(LowerBandsRef, R1, R2);
        case 4:
            LowerCL = AdaptiveMovAvg(LowerBandsRef, R1, R2, R3);
        case 5:
            LowerCL = T3Average.Series(LowerBandsRef, R1);

      { {disable if Juric moving average not installed }
        case 6:
        LowerCL = JRC.JMA.2k(LowerBandsRef, R1, R2);  }
           
        case 7:
            LowerCL = R1;
    end;

end;


{ ESTABLISH FUNCTION }

switch DevID begin
   
    case 1:
        UpperFX = _StdDev(UpperBandsRef, D1b);
    Case 2:
        UpperFX = _StdError(UpperBandsRef, D1b);
    case 3:
        UpperFX = _AvgTrueRange(D1);

    {{ disable if Jurik moving average not installed }   
   case 4:
        UpperFX = _JMATrueRange(D1);}

    case 5:
        UpperFX = UpperBandsRef * D1 / 100;
    case 6:
        UpperFx = D1;

end;
       
if LowerBandsRef = UpperBandsRef then begin
   
    LowerfX = UpperFx;

end else begin

    switch DevID begin 
        case 1:
            LowerFX = _StdDev(LowerBandsRef, D1b); 
        Case 2:
            LowerFX = _StdError(LowerBandsRef, D1b);
        case 3:
            LowerFx = UpperFx; 
        case 4:
            LowerFx = UpperFx; 
        case 5:
            LowerFX = LowerBandsRef * D1 / 100;
        case 6:
            LowerFx = D1;
    end;
       
end;
       
    {  ROUND OFF to tradeable value }
    if RoundToTradable then begin
        for n = 0 to NBands begin
            UpperBand[n] = Round2Fraction(UpperCL + UpperFx*(StartMult+(n-1)*Increment) + AddMinus);
            LowerBand[n] = Round2Fraction(LowerCL - LowerFx*(StartMult+(n-1)*Increment) + AddMinus);
        end;
    { no rounding off }
    end else begin
        for n = 0 to NBands begin
            UpperBand[n] = UpperCL + UpperFx*(StartMult+(n-1)*Increment) + AddMinus;
            LowerBand[n] = LowerCL - LowerFx*(StartMult+(n-1)*Increment) + AddMinus;
        end;
    End;


_RibbonsCalc = 0;

User avatar
TJ
Posts: 6551
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 966 times
Been thanked: 1892 times

Postby TJ » 13 Mar 2010

there are a few more functions to go with this indicator.


p.s. please use the [code] button (on the top of the message window) to wrap your codes.

FHTrader
Posts: 38
Joined: 24 Feb 2010

_RibbonsPlotter indicator's code

Postby FHTrader » 14 Mar 2010

Hi TJ,

Thank you for your reply.
Here are the rest of the functions with that _RibbonsPlotter indicator.
Thank you for your help!



Code: Select all

{
Function:   _AvgTrueRange (Same as AvgTrueRange function)

Note:      In-line code may be faster, but using TrueRange allows function to start Length bars earlier.
          Therefore, I have reverted to using the original TS function, rather than replace TrueRange
         function with inline code.

Author:     Mark J. Krisburg (MarkSanDiego)
 
Date:        05/06/07   original version
          09/06/08   TrueRange function converted to inline code
         01/09/09   TrueRange function returned as allows output to begin (Length - 2) bars earlier
                  This function is now THE SAME as original TS AvgTrueRange function, except that
                  Summation(TrueRange,Length)/Length has replaced Average(TrueRange,Length) to avoid
                  one additional function call.

}

Inputs:
   Length(NumericSimple);    {Length must remain constant}   
 
   _AvgTrueRange = Summation(TrueRange, Length) / Length;

Code: Select all

{   
Function:   _BarsDisplayed

Purpose:    Returns the number of bars visible on the chart.
               
            This function is useful to positioning text and data horizontally on the
            the chart as the user knows how many bars total are displayed.

            The function will return a value of zero until the first bar that is displayed
            at the left margin of the screen appears.  It will then be incremented by
            1 per bar, until LastBarOnChart is reached, at which point, its value will be
            the total number of bars displayed on the chart.

            If the value is tested when LastBarOnChart is reached, the total number of
            displayed bars can be used to then position text horizontally on the screen, so
            it left justified, right justified, centered, or positioned at a percentage of
            the horizontal range displayed.

Notes:      A binary search algorithm would be faster, starting from the LastBarOnChart,
            but this function is called only once per chart loading or refresh,
            so the additional savings from a more efficient algorithm would be minimal.

            Examine the method of calling the function below to see how the function
            is called only once per chart load/refresh.

Author:     MarkSanDiego

Version:    05/17/09    initial version
            07/08/09    modified to not require back references from the LastBarOnChart
                        to avoid increasing the MaxBarsBack for the calling function
                        and preventing the calling indicator from plotting as early as
                        possible.


Usage:  Function should be called once per bar from indicator:

        vars: NBars(0);

        if BarStatus(1) = 2 then NBars = _BarsDisplayed;
}
   
vars:
    float LeftDateTime(0),
    bool StartCount(false),
    int BarsDisplayed(0);


    once begin
        LeftDateTime = GetAppInfo(aiLeftDispDateTime); 
    end;

    { stop comparing current bars date and time to LeftDateTime once left margin bar is reached }
    once (ELDateToDateTime(Date) + ELTimeToDateTime(Time) >= LeftDateTime) begin
        StartCount = true;
    end;

    if StartCount then BarsDisplayed = BarsDisplayed + 1;

    _BarsDisplayed = BarsDisplayed;     



Code: Select all

{
Function:      _DisplayRangeAll

Purpose:      Returns the highest and lowest price displayed on the chart
            and the price range.

            This information can be used to display text messages on a chart in a
            position that will avoid overwriting the price action.

Author:         MarkSanDiego

Version:      05/17/09   initial version
            05/20/09   real time data expands range to include any plotted indicators

Calling Program usage:

vars:
   intrabarpersist DisplayHigh(0),
   intrabarpersist DisplayLow(0),
   intrabarpersist DisplayRange(0);

   value1 = _DisplayRangeAll(DisplayHigh, DisplayLow, DisplayRange);
}


inputs:
   oDisplayHigh(NumericRef),
   oDisplayLow(NumericRef),
   oDisplayRange(NumericRef);

once begin
   oDisplayHigh = GetAppInfo(aiHighestDispValue);
   oDisplayLow = GetAppInfo(aiLowestDispValue);
   oDisplayRange = oDisplayHigh - oDisplayLow;
end;

{ real time data expands range to include any plotted indicators }
once (GetAppInfo(aiRealTimeCalc) = 1) begin
   oDisplayHigh = GetAppInfo(aiHighestDispValue);
   oDisplayLow = GetAppInfo(aiLowestDispValue);
   oDisplayRange = oDisplayHigh - oDisplayLow;
end;


   _DisplayRangeAll = oDisplayRange;



Code: Select all

{
Function:   _JMATrueRange

Purpose:   Faster replacement to AvgTrueRange function.  Converts TrueRange function to in-line code.
   
Author:     Mark J. Krisburg (MarkSanDiego)
 
Date:        05/06/07   original version
          09/06/08   TrueRange function converted to inline code
         01/04/09   inline code produces unexpected outputs during first Length*2 bars
                  Build in TrueRange function restored to code
}

Inputs:
   Length(NumericSimple);       // Length must not change


_JMATrueRange = JRC.JMA.2k(TrueRange, Length, 0);




Code: Select all

// from mmiller Wiki
// substitute for TS LastBarOnChart function which is computation intensive with nested functions.
      
Vars:   IntrabarPersist LBOC(False);

If LBOC = False then LBOC = GetAppInfo(aiRealTimeCalc) = 1 or
      ( Date = JulianToDate(LastCalcJDate) and
       LastCalcMMTime = 60 * IntPortion(Time * 0.01) + 100 * FracPortion(Time * 0.01) ) ;

_LastBarOnChart = LBOC;



Code: Select all

{   
Function:       _RibbonsCalc

Purpose:        This function calculates a series of bands (ribbons) displaced from a
                user specified centerline function.

                The band values are loaded into arrays UpperBand and LowerBand.
                The zero index item (ex. UpperBand[0]) represents the center line value.

Author:         MarkSanDiego

Updated:        09/08/08    original version derived from _RibbonsPlotter indicator
                01/30/09    prevent Standard Deviation function FXParam from being < 1
                05/29/09    clean up and stream line code
                07/08/09    updated to allow centerline to equal the Upper and Lower BandsRef input definition
                07/10/09    VWAP added to centerline functions
                07/12/09    Bug fixed: Ribbons now calculate correctly if StartMult <> 1


CenterLine:     May be:
                0 - Reference value (Upper/Lower BandsRef input value)
                1 - AMA (Arithmetic Average)
                2 - EMA (Exponential Moving Average
                3 - LR (Linear Regression)
                4 - Adaptive Moving Avg (Kaufman - KAMA)
                5 - T3 Triple Exponential Moving Average
                6 - JMA Juric Moving Average or
                7 - WVAP
                8 - Fixed Value

Band Function:  May be:
                1 - Standard Deviation (Bollinger Bands),
                2 - Standard Error (Anderson Bands )
                3 - Average True Range - ATR (Keltner Bands)
                4 - Jurik Average True Range (ATR using Jurik Moving Avg)
                5 - Percentage
                6 - Points

}
{

Usage:

Inputs:     
    Price(low),
    Smooth(0),

    UpperBandsRef(TypicalPrice),
    LowerBandsRef(TypicalPrice),

    RefID(3),
    AMALength(15),                  { arithmetic moving average length }
    EMALength(15),                  { exponential moving average length }
    LRLength(15),                   { linear regression function length }
    LRTgtBar(0),                    { linear regression function target bar }
    KAMA_EffRatioLen(7),            { Kaufman adaptive moving average parameters }
    KAMA_FastLength(2),             { Kaufman adaptive moving average parameters }
    KAMA_SlowLength(25),            { Kaufman adaptive moving average parameters }
    T3Length(20),
    JMALength(20),
    JMAPhase(0),
    RefValue(0),

    DevID(5),                       { deviation function identifier }
    StdDevLength(15),               { standard deviation length }
    StdErrLength(15),               { standard error length }
    ATRLength(14),                  { average true range length }
    JATRLength(14),                 { percentage }
    Percent(1),                         
    Pts(1),

    NBands(2),                      { maximum 8 }
    StartMult(1),
    Increment(1),
    AddMinus(0),
    RoundToTradable(False),
   
    PlotWidth(0),
    ShowCenterLine(true);

Arrays:
    UpperBand[9](0),                { array containing band values.  UpperBand[0] is the center line value }
    LowerBand[9](0),                { array containing band values.  UpperBand[0] is the center line value }
    RefParam[4](0),                 { reference function (center line) parameters }
    DevParam[4](0);                 { deviation function (bands or ribbons) parameters }

Variables: 
    UpperCL(0),
    LowerCL(0); 


        Value1 = _RibbonsCalc(UpperBandsRef, LowerBandsRef, RefParam, DevParam,
            NBands, StartMult, Increment, AddMinus, RoundToTradable, UpperBand, LowerBand);

}


Inputs:     
    UpperBandsRef(NumericSeries),
    LowerBandsRef(NumericSeries),

    RefParam[xx](NumericArrayRef),
    DevParam[yy](NumericArrayRef),

    NBands(NumericSimple),
    StartMult(NumericSimple),
    Increment(NumericSimple),
    AddMinus(NumericSimple),
    RoundToTradable(TrueFalseSimple),

{ Arrays: }
    UpperBand[tt](NumericArrayRef),
    LowerBand[uu](NumericArrayRef);

Variables: 
    intrabarpersist RefID(0),           { reference function ID }
    R1(0),                              { reference function parameters }
    R2(0),
    R3(0),
    R4(0),
    DevID(0),                           { deviation function ID }
    D1(0),                              { deviation function paramaters }
    D1b(0),                             { special handling required for standard dev and standard error functions }             
    D2(0),
    D3(0),
    D4(0),

    n(0),
    x(0),
    StartBar(0),
    intrabarpersist UpperFX(0),
    intrabarpersist LowerFX(0),
    intrabarpersist UpperCL(0),
    intrabarpersist LowerCL(0); 


{ unpack static reference and deviation function parameters }
       
once begin

    RefID = RefParam[0];
    R1 = RefParam[1];
    R2 = RefParam[2];
    R3 = RefParam[3];
    R4 = RefParam[4];

    DevID = DevParam[0];
    D1 = DevParam[1];
    D1b = MaxList(2, D1);               { special handling required for standard dev and standard error functions }
    D2 = DevParam[2];
    D3 = DevParam[3];
    D4 = DevParam[4];

end;
   
{ ESTABLISH CENTERLINE }

switch RefID begin
    Case 0:
        UpperCL = UpperBandsRef;
    case 1:
        UpperCL = AverageFC(UpperBandsRef, R1);
    case 2:
        UpperCL = XAverage(UpperBandsRef, R1);
    case 3:
        UpperCL = LinearRegValue(UpperBandsRef, R1, R2);
    case 4:
        UpperCL = AdaptiveMovAvg(UpperBandsRef,  R1, R2, R3);
    case 5:
        UpperCL = T3Average.Series(UpperBandsRef, R1);

{}
    {disable if Juric moving average not installed }
   { case 6:
        UpperCL = JRC.JMA.2k(UpperBandsRef, R1, R2);
}
    case 7:
        UpperCL = _VWAP;       
           
    case 8:
        UpperCL = R1;
end;
   

if LowerBandsRef = UpperBandsRef  then begin
   
    LowerCL = UpperCL;

end else begin

    switch RefID begin
        Case 0:
            LowerCL = LowerBandsRef;
        case 1:
            LowerCL = AverageFC(LowerBandsRef, R1);
        case 2:
            LowerCL = XAverage(LowerBandsRef, R1);
        case 3:
            LowerCL = LinearRegValue(LowerBandsRef, R1, R2);
        case 4:
            LowerCL = AdaptiveMovAvg(LowerBandsRef, R1, R2, R3);
        case 5:
            LowerCL = T3Average.Series(LowerBandsRef, R1);

        {disable if Juric moving average not installed }
        {case 6:
            LowerCL = JRC.JMA.2k(LowerBandsRef, R1, R2); 
             }
        case 7:
            LowerCL = _VWAP;               
           
        case 8:
            LowerCL = R1;
    end;

end;

{ ESTABLISH FUNCTION }

switch DevID begin
   
    case 1:
        UpperFX = _StdDev(UpperBandsRef, D1b);
    Case 2:
        UpperFX = _StdError(UpperBandsRef, D1b);
    case 3:
        UpperFX = _AvgTrueRange(D1);

    { disable if Jurik moving average not installed }   
    {case 4:
        UpperFX = _JMATrueRange(D1);
}
    case 5:
        UpperFX = UpperBandsRef * D1 / 100;
    case 6:
        UpperFx = D1;

end;
       
if LowerBandsRef = UpperBandsRef then begin

    LowerfX = UpperFx;

end else begin

    switch DevID begin 
        case 1:
            LowerFX = _StdDev(LowerBandsRef, D1b); 
        Case 2:
            LowerFX = _StdError(LowerBandsRef, D1b);
        case 3:
            LowerFx = UpperFx; 
        case 4:
            LowerFx = UpperFx; 
        case 5:
            LowerFX = LowerBandsRef * D1 / 100;
        case 6:
            LowerFx = D1;
    end;
       
end;
       
   
    {  ROUND OFF to tradeable value }
    if RoundToTradable then begin
        for n = 0 to NBands begin
            if n = 0 then x = 0
                else x = StartMult + (n - 1) * Increment;
            UpperBand[n] = Round2Fraction(UpperCL + x * UpperFx + AddMinus);
            LowerBand[n] = Round2Fraction(LowerCL - x * LowerFx + AddMinus);
        end;
    { no rounding off }
    end else begin
        for n = 0 to NBands begin
            if n = 0 then x = 0
                else x = StartMult + (n - 1) * Increment;
            UpperBand[n] = UpperCL + x * UpperFx + AddMinus;
            LowerBand[n] = LowerCL - x * LowerFx + AddMinus;
        end;
    End;


_RibbonsCalc = 0;





Code: Select all

{
Function:      _StdDev   (Standard Deviation)

Purpose:      Calculate the standard deviation, using a wrapper function to obtain results from
            _StdDevMean, which provides both Standard Deviation and Mean value results.
            
            Timing tests reveal that addition of the wrapper does not add significantly to
            processing times:
            
            _StdDevMean called directly:              28-30 uSec
            _StdDevSA (wrapper for _StdDevMeanSA):      32-33 uSec (slightly faster ??)

            Timing tests showed calling _StdDevMean thru the wrapper routine, _StdDev, is only 3-4 uSec
            slower than calling _StdDevMean directly.

Timing:         TS StdDev function call:         65-68 uSec
            _StdDev wrapper for _StdDevMean:   31-34 uSec
            _StdDevMean function            27     uSec
            _StdDevMeanSA function            17-18 uSec
            in line _StdDevMean               19-21 uSec
            in line _StdDevMeanSA            17-19 uSec

Author:         Mark J. Krisburg (MarkSanDiego)


Updated:      09/01/08   original version
            05/03/09   reverted this method to match _StdDevMeanFC
}               


inputs:
   Price(NumericSeries),
   Length(NumericSimple);               { length used to measure average and standard deviation }
      
variables:
   float x(0),
   float oMean(0),
   float oStdDev(0);               

arrays:
   float static[500](0);   


   x = _StdDevMean(Price, Length, 1, oMean, oStdDev);   
   
   _StdDev = oStdDev;   



Code: Select all

{
Function:      _StdDevMeanFC   (Standard Deviation Fast Calculation)

Note:         _StdDevMean now adjusts its summation method according to whether Length varies.
            This eliminates the need to use a separate function (_StdDevMeanFC) for situations
            where Length does NOT vary.  _StdDevMeanFC is only fractionally faster than
            _StdDevMean.

Purpose:      Calculate the mean and standard deviation in single function using an alternative
            algorithm to calculation standard deviation described in Wikipedia.

            Because coding techniques similar to SummationFC are used, standard deviation
            LENGTH MUST NOT VARY from bar to bar.  If standard deviation length must vary,
            then use function _StdDevMean or the TS built-in functions.

Discussion:      The TS standard deviation functions do not ouput the mean used in calculating the
            standard deviation.  Therefore, in many custom routines that use both mean and
            standard deviation, such as Bollinger Bands and Z-Score, there is duplication of
            the mean calculation.

            This routine returns both the mean and the standard deviation in a single function
            and therefore avoids the necessity of performing a repeat calculation of the mean.

Source:         Casey (TS forums) found this method, described in Wikipedia
            
Author:         MarkSanDiego

Updated:      08/28/08   original version
            02/19/09   alternative method of calculating standard deviation implemented
            02/21/09   documentation improved


Put the following in calling routine:

{ CALLING ROUTINE USAGE STARTS HERE }

inputs:   
   Price(Close),                  
   Length(100),                     // length used to measure average and standard deviation
   DataType(1),                     // = 1 for Variance and standard deviation of entire population; 
                                 // = 2 for Variance and standard deviation of sample of population

vars:                           
   oMean(0),                        // average price; oAvg = Average(Price, Length)
   oStdDev(0);                        // standard deviation of price; oSD = StandardDev(Price, Length)


   value1 = _StdDevMeanFC(Price, Length, DataType, oMean, oStdDev);

{ CALLING ROUTINE USAGE STOPS HERE }
}


inputs:
   Price(NumericSeries),
   Length(NumericSimple),               // length used to measure average and standard deviation
                                 // should be multiple of longest Length of input
   DataType(NumericSimple),            // = 1 for Variance and standard deviation of entire population; 
                                 // = 2 for Variance and standard deviation of sample of population                                                         
{ outputs: }
   oMean(NumericRef),                  // average price; oMean = Average(Price, Length)
   oStdDev(NumericRef);                // standard deviation of price series; oSD = StandardDev(Price), Length)
      
variables:
   x(0),         
   rLen(1/Length),
   Divisor(0),                        // divisor used for variance of entire/sample population
   rDiv(0),                        // inverse of divisor to allow faster multiplication
   Sum(0),                           // sum used to calculate Mean
   SumSq(0),                        // sum of squares of (Price - oMean)
   MeanSq(0);         


{ INLINE CODE STARTS HERE: Function _StdDevMean }
 
{ uncomment this section when extrcting this function for in-line code }
{
inputs:   
   Price(Close),                  
   Length(100),         // length used to measure average and standard deviation
   DataType(1),         // = 1 for Variance and standard deviation of entire population; 
                     // = 2 for Variance and standard deviation of sample of population

vars:                           
   oMean(0),            // average price; oAvg = Average(Price, Length)
   oStdDev(0);            // standard deviation of price; oSD = StandardDev(Price, Length)
}


once begin
   
   if DataType = 1 then begin
      Divisor = Length;
      if Length < 1 then RaiseRunTimeError("For StdDev of entire population: Length must be >= 1");
   end else begin
      Divisor = Length - 1;
      if Length < 2 then RaiseRunTimeError("For StdDev of sample of population: Length must be >= 2");
   end;

   rDiv = 1/Divisor;
      
   for value1 = 1 to Length begin
      x = Price[value1];
      Sum = Sum + x;
      SumSq = SumSq + x * x;
   end ;

end;

   {inline SummactionFC function}
   x = Price[Length];
   Sum = Sum + Price - x ;
   SumSq = SumSq + Price * Price - x * x;

   oMean = Sum * rLen;
   MeanSq = SumSq * rLen;
   x = MeanSq - oMean * oMean;
   if x > 0 then
      oStdDev = SquareRoot( x )
   else
      oStdDev = 0;

{ INLINE CODE STOPS HERE }

   _StdDevMean = oStdDev;




Code: Select all

{ Standard Error of Estimate (the predicted y-value), SEE }

inputs:
   Price( numericseries ),
   Length( numericsimple ) ; { Length > 2 }

variables:
   AvgX( 0 ),
   AvgY( 0 ),
   Dx( 0 ),
   Dy( 0 ),
   SumDxSqr( 0 ),
   SumDySqr( 0 ),
   SumDxDy( 0 ) ;

Once begin
   if Length <= 2 then RaiseRunTimeError("Function _StdError requires Length > 2");
   AvgX = Length * ( Length - 1 ) * .5 / Length ;
end;

_StdError = 0 ;
   AvgY = AverageFC( Price, Length ) ;
   SumDxSqr = 0 ;
   SumDySqr = 0 ;
   SumDxDy = 0 ;
   for Value1 = 0 to Length - 1
      begin
      Dx = Value1 - AvgX ;
      Dy = Price[Value1] - AvgY ;
      SumDxSqr = SumDxSqr + (Dx * Dx) ;
      SumDySqr = SumDySqr + (Dy * Dy ) ;
      SumDxDy = SumDxDy + Dx * Dy ;
      end ;
   Value2 = ( SumDySqr - Square( SumDxDy ) / SumDxSqr ) / ( Length - 2 ) ;
   if Value2 > 0 then begin
      _StdError = SquareRoot( Value2 );
   end else
       _StdError = 0;



Code: Select all

[LegacyColorValue = TRUE];

[LegacyColorValue = true];

variables:
   PriceW(0) ,
   ShareW(0) ,
   TotTicks(0);

if date > date[ 1 ] then
begin
   PriceW = 0 ;
   ShareW = 0 ;   
end ;

TotTicks = UpTicks + DownTicks;
PriceW = PriceW + ( AvgPrice * ( TotTicks ) ) ;
ShareW = ShareW + ( TotTicks ) ;

if ShareW > 0 then
   _VWAP = PriceW / ShareW ;



Code: Select all

[LegacyColorValue = TRUE];

[LegacyColorValue = true];


Inputs:       Price(NumericSeries), Periods(NumericSimple);

Variables:   b(0), b2(0), b3(0), e1(Price), e2(Price), e3(Price),
            e4(Price), e5(Price), e6(Price), c1(0), c2(0), c3(0),
            c4(0), f1(0), f2(0), Hot(0.7);

if Periods + 1 <> 0 then begin

   if CurrentBar <= 1 then begin

      b  = Hot;
      b2 = b * b;
      b3 = b * b * b;
      c1   = -b3;
      c2 = 3 * b2 + 3 * b3;
      c3 = -6 * b2 - 3 * b - 3 * b3;
      c4 = 1 + 3 * b + b3 + 3 * b2;
      f1 = 2 / (Periods + 1);
      f2 = 1 - f1;

   end else begin

      e1 = f1 * Price + f2 * e1[1];
      e2 = f1 * e1 + f2 * e2[1];
      e3 = f1 * e2 + f2 * e3[1];
      e4 = f1 * e3 + f2 * e4[1];
      e5 = f1 * e4 + f2 * e5[1];
      e6 = f1 * e5 + f2 * e6[1];

   end;

   T3Average.series = c1 * e6 + c2 * e5 + c3 * e4 + c4 * e3;

end;




Code: Select all

{
Indicator:      _RibbonsPlotter

Description:    This Indictor plots various types of ribbons (multiple bands of deviation functions)
                around a centerline reference function.

Provided By:    Mark J. Krisburg (MarkSanDiego)

Updated:        02/18/07    original version
                09/14/08    fixed offset
                01/03/09    lower band function formula error correction
                01/04/09    future projections added (FutureOffset = 1 or 2)
                04/30/09    clean up and tighten code
                05/29/09    add display of input parameters on chart
                07/08/09    _BarsDisplayed function modified to minimize increase in MaxBarsBack
                            cause by back referencing to print chart labels after LastBarOnChart
                            reached.
                07/10/09    WVAP added as to centerline functions   
               
************************************************************************************** 
                { Reference Function (Center line) May be: }       
                0-Zero axis
                1-AMA (Arithmetic Average)
                2-EMA (Exponential Moving Average
                3-LR (Linear Regression)
                4-Adaptive Moving Avg (Kaufman - KAMA)
                5-T3 Triple Exponential Moving Average
                6-JMA Juric Moving Average or
                7-WVAP
                8-Fixed Value

                { Deviation Function (Band or Ribbons) may be: }
                1-Standard Deviation (Bollinger Bands)
                2-Standard Error
                3-ATR (Average True Range - Keltner Bands)
                4 JMA True Range (ATR using Jurik Moving Avg)
                5-Pct (Percentage)
                6-Points
**************************************************************************************
}
                   
[LegacyColorValue = true];

Inputs:     
    Price(low),
    Smooth(0),

    UpperBandsRef(TypicalPrice),
    LowerBandsRef(TypicalPrice),
    Offset(0),

    RefID(3),
    AMALength(15),                  { arithmetic moving average length }
    EMALength(15),                  { exponential moving average length }
    LRLength(15),                   { linear regression function length }
    LRTgtBar(0),                    { linear regression function target bar }
    KAMA_EffRatioLen(7),            { Kaufman adaptive moving average parameters }
    KAMA_FastLength(2),             { Kaufman adaptive moving average parameters }
    KAMA_SlowLength(25),            { Kaufman adaptive moving average parameters }
    T3Length(20),
    JMALength(20),
    JMAPhase(0),
    VWAP("No Param RefID = 7"),
    RefValue(0),

    DevID(1),                        { deviation function identifier }
    StdDevLength(15),                { standard deviation length }
    StdErrLength(15),                { standard error length }
    ATRLength(14),                   { average true range length }
    JATRLength(14),                  { percentage }
    Percent(1),                         
    Pts(1),

    NBands(3),                       { maximum 8 }
    StartMult(1),
    Increment(1),
    AddMinus(0),
    RoundToTradable(False),
   
    PlotWidth(0),
    ShowCenterLine(true),
    DisplayParameters(true),         { display chart parameters }
    CLParamColor(yellow),            { center line parameters display color }
    DevParamColor(cyan),             { deviation parameters display color }
    CLVertPct(8),                    { vertical position in chart range percent for center line parameter display }
    DevVertPct(3),                   { vertical position in chart range percent for deviation parameter display }
    CLHorizPct(50),                  { horizontal position in percent for center line parameter display
                                       [leftmost = zero %, rightmost = 100%] }
    DevHorizPct(50);                 { horizontal position in percent for deviation parameter display
                                       [leftmost = zero %, rightmost = 100%] }

Arrays:
    UpperBand[9](0),
    LowerBand[9](0),
    RefParam[4](0),                  { reference function (center line) parameters }
    DevParam[4](0);                  { deviation function (bands or ribbons) parameters }

Variables:     
    UpperCL(0),
    LowerCL(0),
   
    { chart display parameters }
    intrabarpersist string Text1("Center Line:     "),       
    intrabarpersist string Text2("    Deviation:     "),
    intrabarpersist TextVertPct1(CLVertPct),
    intrabarpersist TextVertPct2(DevVertPct),
    intrabarpersist TextHorizPct1(CLHorizPct),
    intrabarpersist TextHorizPct2(DevHorizPct),
    intrabarpersist TextVert1(0),
    intrabarpersist TextVert2(0),
    intrabarpersist int TextOffset1(0),
    intrabarpersist int TextOffset2(0),
    intrabarpersist DisplayHigh(0),
    intrabarpersist DisplayLow(0),
    intrabarpersist DisplayRange(0),
    intrabarpersist BarsDisplayed(0),
    intrabarpersist TextID1(0),
    intrabarpersist TextID2(0),
    intrabarpersist RangePctAtOffset(0),
    intrabarpersist TextLength1(0),
    intrabarpersist TextLength2(0),
    intrabarpersist TextMaxLength(0);


{ pack reference and deviation function parameters into arrays }

Once begin
       
    { initialize display parameters text strings }
           

    { Reference function parameters }
    RefParam[0] = RefID;
    switch RefID begin
        Case 0:
            RefParam[1] = 0;
            Text1 = Text1 & "Zero axis";
        Case 1:
            RefParam[1] = AMALength;
            Text1 = Text1 & "AMA " & NumToStr(AMALength, 0);
        Case 2:
            RefParam[1] = EMALength;
            Text1 = Text1 & "EMA " & NumToStr(EMALength, 1);               
        Case 3:
            RefParam[1] = LRLength;
            RefParam[2] = LRTgtBar;
            Text1 = Text1 & "LinReg " & NumToStr(LRLength, 0)
                & "  Offset " & NumToStr(Offset,0) & "  TgtBar " & NumToStr(LRTgtBar, 0);
        Case 4:
            RefParam[1] = KAMA_EffRatioLen;
            RefParam[2] = KAMA_FastLength;
            RefParam[3] = KAMA_SlowLength;
            Text1 = Text1 & "KAMA " & NumToStr(KAMA_EffRatioLen, 1)
                & ", " & NumToStr(KAMA_FastLength, 1) & ", " & NumToStr(KAMA_SlowLength, 1);
        Case 5:
            RefParam[1] = T3Length;
            Text1 = Text1 & "T3  " & NumToStr(T3Length, 0);
        Case 6:
            RefParam[1] = JMALength;
            RefParam[2] = JMAPhase;
            Text1 = Text1 & "JMA " & NumToStr(JMALength, 0) & "  Phase " & NumToStr(JMAPhase, 0);
        Case 7:
            Text1 = Text1 & "VWAP";   
               
        Case 8:
            RefParam[1] = RefValue;
            Text1 = Text1 & "Value = " & NumToStr(RefValue, 1);
    end;

    { Deviation function parameters }
    DevParam[0] = DevID;
    switch DevID begin
        Case 1:
            DevParam[1] = StdDevLength;
            Text2 = Text2 & "Std Dev " & NumToStr(StdDevLength, 0);
        Case 2:
            DevParam[1] = StdErrLength;
            Text2 = Text2 & "Std Err " & NumToStr(StdErrLength, 0);
        Case 3:
            DevParam[1] = ATRLength;
            Text2 = Text2 & "ATR " & NumToStr(ATRLength, 0);
        Case 4:
            DevParam[1] = JATRLength;
            Text2 = Text2 & "JURIC ATR " & NumToStr(JATRLength, 0);
        Case 5:
            DevParam[1] = Percent;
            Text2 = Text2 & "Percent " & NumToStr(Percent, 1);
        Case 6:
            DevParam[1] = Pts;
            Text2 = Text2 & "Points " & NumToStr(Pts, 2);
    end;


    TextID1 = Text_New(0, 0, 0, Text1);
    TextID2 = Text_New(0, 0, 0, Text2);
    value1 = Text_SetColor(TextID1, CLParamColor);
    value2 = Text_SetColor(TextID2, DevParamColor);

    TextLength1 = StrLen(Text1);
    TextLength2 = StrLen(Text2);
    TextMaxLength = MaxList(TextLength1, TextLength2);

end;
   


    Value1 = _RibbonsCalc(UpperBandsRef[Offset], LowerBandsRef[Offset], RefParam, DevParam,
                NBands, StartMult, Increment, AddMinus, RoundToTradable, UpperBand, LowerBand);

      { PLOTTING }
    If NBands >= 1 Then Begin
        Plot8(UpperBand[1],"Hi-1", default, default, PlotWidth);
        Plot10(LowerBand[1],"Lo-1", default, default, PlotWidth);
               
        If NBands >=2 Then Begin
            Plot7(UpperBand[2],"Hi-2", default, default, PlotWidth);
            Plot11(LowerBand[2],"Lo-2", default, default, PlotWidth);
               
            If NBands >=3 Then Begin
                Plot6(UpperBand[3],"Hi-3", default, default, PlotWidth);
                Plot12(LowerBand[3],"Lo-3", default, default, PlotWidth);
 
                If NBands >= 4 Then Begin
                    Plot5(UpperBand[4],"Hi-4", default, default, PlotWidth);
                    Plot13(LowerBand[4],"Lo-4", default, default, PlotWidth);

                    If NBands >= 5 Then Begin
                        Plot4(UpperBand[5],"Hi-5", default, default, PlotWidth);
                        Plot14(LowerBand[5],"Lo-5", default, default, PlotWidth);
                                             
                        If NBands >=6 Then Begin
                            Plot3(UpperBand[6], "Hi-6", default, default, PlotWidth);
                            Plot15(LowerBand[6],"Lo-6", default, default, PlotWidth);
                                           
                            If NBands >=7 Then Begin
                                Plot2(UpperBand[7],"Hi-7", default, default, PlotWidth);
                                Plot16(LowerBand[7],"Lo-7", default, default, PlotWidth);
                       
                                If NBands >=8 Then Begin
                                    Plot1(UpperBand[8],"Hi-8", default, default, PlotWidth);
                                    Plot17(LowerBand[8],"Lo-8", default, default, PlotWidth);
                                End;
                            End;
                        End;
                    End;
                End;
            End;
        End;   
    End;

    if ShowCenterLine then begin
        Plot9(UpperBand[0] + AddMinus,"URef", default, default, PlotWidth);
        If LowerBand[0] <> UpperBand[0] Then Plot18(LowerBand[0] + AddMinus,"LRef", default, default, PlotWidth);
    end;


    if Smooth > 0 then Plot21(Average(Price, Smooth), "Smooth Price");
    //if Smooth > 0 then Plot21(JRC.JMA.2k(Price, Smooth,0), "Smooth Price");
   

    { chart label section }
    { adding this section causes ribbon plotter to delay plotting for first 200 bars }
    { may wish to comment out this section if using ribbon plotter for strategy testing }
    { since almost 200 more bars of data will be available to analyze }         

    BarsDisplayed = _BarsDisplayed;

    if _LastBarOnChart then begin
       
        if DisplayParameters then begin

            switch RefID begin
                case 0, 7:
                    value1 = _DisplayRangeAll( DisplayHigh, DisplayLow, DisplayRange );

                default:
                    DisplayHigh = Highest(MaxList(UpperBand[NBands], High), BarsDisplayed);
                    DisplayLow = Lowest(MinList(LowerBand[NBands], Low), BarsDisplayed);
                    DisplayRange = DisplayHigh - DisplayLow;
            end;
           
            TextOffset1 = BarsDisplayed * (1 - TextHorizPct1 / 100) + TextMaxLength/2;
            TextOffset2 = BarsDisplayed * (1 - TextHorizPct2 / 100) + TextMaxLength/2;

            { determine range percent of price at middle of text string }
            RangePctAtOffset = (Close[(TextOffset1 + TextOffset2 - TextMaxLength)/2] - DisplayLow) / DisplayRange; 

            if RangePctAtOffset > 0.50 then begin
                TextVert1 = DisplayLow + DisplayRange * TextVertPct1 / 100;
                TextVert2 = DisplayLow + DisplayRange * TextVertPct2 / 100;
            end else begin
                TextVert1 = DisplayHigh - DisplayRange * TextVertPct2 / 100;
                TextVert2 = DisplayHigh - DisplayRange * TextVertPct1 / 100;
            end;

            value3 = Text_SetLocation(TextID1, Date[TextOffset1], Time[TextOffset1], TextVert1);
            value4 = Text_SetLocation(TextID2, Date[TextOffset2], Time[TextOffset2], TextVert2);
        end;   
    end;
{}
   
// debug:
//print(_DateTimeSymbol,TextID1,TextID2,TextOffset1,TextOffset2,DisplayLow,DisplayHigh,DisplayRange,TextVert1,TextVert2);

User avatar
TJ
Posts: 6551
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 966 times
Been thanked: 1892 times

Postby TJ » 15 Mar 2010

you are still missing this function:

JRC.JMA.2k

FHTrader
Posts: 38
Joined: 24 Feb 2010

Postby FHTrader » 16 Mar 2010

Hi TJ,

That JRC.JMA.2k function is not the problem as I already commented out the section of codes that requires it. BTW, JMA is 3rd party function code from a software vendor.

Thanks.

User avatar
TJ
Posts: 6551
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 966 times
Been thanked: 1892 times

Postby TJ » 16 Mar 2010

Code: Select all

Inputs:     
    Price(low),
    Smooth(0),


what numbers have you used for smooth?

FHTrader
Posts: 38
Joined: 24 Feb 2010

Postby FHTrader » 17 Mar 2010

Hi TJ,

I had used it without any problem with TS. I did however test it using different smooth value. it still shows Error of Floating-point invalid operation.

Thanks.

User avatar
TJ
Posts: 6551
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 966 times
Been thanked: 1892 times

Postby TJ » 19 Mar 2010

give this a try.
Attachments
_RibbonsPlotter (TJ-1).txt
(12.79 KiB) Downloaded 224 times

FHTrader
Posts: 38
Joined: 24 Feb 2010

Postby FHTrader » 19 Mar 2010

Hi TJ,

Thanks for helping me. I was able to use the indicator without the error of floating-point. but it only plots a single horizontal line when it's supposed to plot 3 bands according to the input value.

Does it show one horizontal line or 3 bands on yours?

Thank you!

User avatar
TJ
Posts: 6551
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 966 times
Been thanked: 1892 times

Postby TJ » 19 Mar 2010

Hi TJ,

Thanks for helping me. I was able to use the indicator without the error of floating-point. but it only plots a single horizontal line when it's supposed to plot 3 bands according to the input value.

Does it show one horizontal line or 3 bands on yours?

Thank you!


I have a straight line as well.
Probably it has to do with the input settings.

User avatar
TJ
Posts: 6551
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 966 times
Been thanked: 1892 times

Postby TJ » 31 Mar 2010


FHTrader
Posts: 38
Joined: 24 Feb 2010

Postby FHTrader » 31 Mar 2010

Hi TJ,

Thanks for your post. I did see that new thread.
I did make it work and found that it's not what I am looking for. So I am not going to persue any further with this thread.
Many thanks for your kind help and replies. Hope others found this Ribbon plotter to be helpful to their trading.

User avatar
TJ
Posts: 6551
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 966 times
Been thanked: 1892 times

Postby TJ » 31 Mar 2010

Hi TJ,

Thanks for your post. I did see that new thread.
I did make it work and found that it's not what I am looking for. So I am not going to persue any further with this thread.
Many thanks for your kind help and replies. Hope others found this Ribbon plotter to be helpful to their trading.


When you have made something work, as a courtesy, you should post your findings.

.

smashthepound
Posts: 82
Joined: 20 Jun 2009
Been thanked: 1 time

Postby smashthepound » 31 Mar 2010

FHTrader, can you tell me which changes you made? Thanks.

FHTrader
Posts: 38
Joined: 24 Feb 2010

Postby FHTrader » 01 Apr 2010

Hi to all,
Trust me, I would be very willing to help you guys to make it work, the same way as TS. It's probably a minor changes somewhere for those with coding talent after all it's EasyLanguage.

I did some changes here using my very limited coding skill. Hope those with coding talent will not laught at me and HELP instead.


Code: Select all

{
Function:       _RibbonsCalc

Purpose:        This function calculates a series of bands (ribbons) displaced from a
                user specified centerline function.

                The band values are loaded into arrays UpperBand and LowerBand.
                The zero index item (ex. UpperBand[0]) represents the center line value.

Author:         MarkSanDiego

Updated:        09/08/08    original version derived from _RibbonsPlotter indicator
                01/30/09    prevent Standard Deviation function FXParam from being < 1
                05/29/09    clean up and stream line code


CenterLine:     May be:
                0 - Zero axis
                1 - AMA (Arithmetic Average)
                2 - EMA (Exponential Moving Average
                3 - LR (Linear Regression)
                4 - Adaptive Moving Avg (Kaufman - KAMA)
                5 - T3 Triple Exponential Moving Average
                6 - JMA Juric Moving Average or
                7 - Fixed Value

Band Function:  May be:
                1 - Standard Deviation (Bollinger Bands),
                2 - Standard Error (Anderson Bands )
                3 - Average True Range - ATR (Keltner Bands)
                4 - Jurik Average True Range (ATR using Jurik Moving Avg)
                5 - Percentage
                6 - Points

}
{

Usage:

Inputs:     
    Price(low),
    Smooth(0),

    UpperBandsRef(TypicalPrice),
    LowerBandsRef(TypicalPrice),

    RefID(3),
    AMALength(15),                  { arithmetic moving average length }
    EMALength(15),                  { exponential moving average length }
    LRLength(15),                   { linear regression function length }
    LRTgtBar(0),                    { linear regression function target bar }
    KAMA_EffRatioLen(7),            { Kaufman adaptive moving average parameters }
    KAMA_FastLength(2),             { Kaufman adaptive moving average parameters }
    KAMA_SlowLength(25),            { Kaufman adaptive moving average parameters }
    T3Length(20),
    JMALength(20),
    JMAPhase(0),
    RefValue(0),

    DevID(5),                       { deviation function identifier }
    StdDevLength(15),               { standard deviation length }
    StdErrLength(15),               { standard error length }
    ATRLength(14),                  { average true range length }
    JATRLength(14),                 { percentage }
    Percent(1),                         
    Pts(1),

    NBands(2),                      { maximum 8 }
    StartMult(1),
    Increment(1),
    AddMinus(0),
    RoundToTradable(False),
   
    PlotWidth(0),
    ShowCenterLine(true);

Arrays:
    UpperBand[9](0),                { array containing band values.  UpperBand[0] is the center line value }
    LowerBand[9](0),                { array containing band values.  UpperBand[0] is the center line value }
    RefParam[4](0),                 { reference function (center line) parameters }
    DevParam[4](0);                 { deviation function (bands or ribbons) parameters }

Variables: 
    UpperCL(0),
    LowerCL(0); 


        Value1 = _RibbonsCalc(UpperBandsRef, LowerBandsRef, RefParam, DevParam,
            NBands, StartMult, Increment, AddMinus, RoundToTradable, UpperBand, LowerBand);

}


Inputs:     
    UpperBandsRef(NumericSeries),
    LowerBandsRef(NumericSeries),

    RefParam[xx](NumericArrayRef),
    DevParam[yy](NumericArrayRef),

    NBands(NumericSimple),
    StartMult(NumericSimple),
    Increment(NumericSimple),
    AddMinus(NumericSimple),
    RoundToTradable(TrueFalseSimple),

{ Arrays: }
    UpperBand[tt](NumericArrayRef),
    LowerBand[uu](NumericArrayRef);

Variables: 
    intrabarpersist RefID(0),           { reference function ID }
    R1(0),                              { reference function parameters }
    R2(0),
    R3(0),
    R4(0),
    DevID(0),                           { deviation function ID }
    D1(0),                              { deviation function paramaters }
    D1b(0),                             { special handling required for standard dev and standard error functions }             
    D2(0),
    D3(0),
    D4(0),

    n(0),
    StartBar(0),
    intrabarpersist UpperFX(0),
    intrabarpersist LowerFX(0),
    intrabarpersist UpperCL(0),
    intrabarpersist LowerCL(0); 


{ unpack static reference and deviation function parameters }
       
once begin

    RefID = RefParam[0];
    R1 = RefParam[1];
    R2 = RefParam[2];
    R3 = RefParam[3];
    R4 = RefParam[4];

    DevID = DevParam[0];
    D1 = DevParam[1];
    D1b = MaxList(2, D1);               { special handling required for standard dev and standard error functions }
    D2 = DevParam[2];
    D3 = DevParam[3];
    D4 = DevParam[4];

end;
   
{ ESTABLISH CENTERLINE }

switch RefID begin
    Case 0:
        UpperCL = 0;
    case 1:
        UpperCL = AverageFC(UpperBandsRef, R1);
    case 2:
        UpperCL = XAverage(UpperBandsRef, R1);
    case 3:
        UpperCL = LinearRegValueFC(UpperBandsRef, R1, R2);
   end;
   

if LowerBandsRef = UpperBandsRef  then begin
   
    LowerCL = UpperCL;

end else begin

    switch RefID begin
        Case 0:
            LowerCL = 0;
        case 1:
            LowerCL = AverageFC(LowerBandsRef, R1);
        case 2:
            LowerCL = XAverage(LowerBandsRef, R1);
        case 3:
            LowerCL = LinearRegValueFC(LowerBandsRef, R1, R2);
            end;

end;


{ ESTABLISH FUNCTION }

switch DevID begin
   
    case 1:
        UpperFX = _StdDev(UpperBandsRef, D1b);
    Case 2:
        UpperFX = _StdError(UpperBandsRef, D1b);
end;
       
if LowerBandsRef = UpperBandsRef then begin
   
    LowerfX = UpperFx;

end else begin

    switch DevID begin 
        case 1:
            LowerFX = _StdDev(LowerBandsRef, D1b); 
        Case 2:
            LowerFX = _StdError(LowerBandsRef, D1b);
        end;
       
end;
       
    {  ROUND OFF to tradeable value }
    if RoundToTradable then begin
        for n = 0 to NBands begin
            UpperBand[n] = Round2Fraction(UpperCL + UpperFx*(StartMult+(n-1)*Increment) + AddMinus);
            LowerBand[n] = Round2Fraction(LowerCL - LowerFx*(StartMult+(n-1)*Increment) + AddMinus);
        end;
    { no rounding off }
    end else begin
        for n = 0 to NBands begin
            UpperBand[n] = UpperCL + UpperFx*(StartMult+(n-1)*Increment) + AddMinus;
            LowerBand[n] = LowerCL - LowerFx*(StartMult+(n-1)*Increment) + AddMinus;
        end;
    End;


_RibbonsCalc_MYWAY = 0;

Code: Select all

{
Indicator:      _RibbonsPlotter

Description:    This Indictor plots various types of ribbons (multiple bands of deviation functions)
                around a centerline reference function.

Provided By:    Mark J. Krisburg (MarkSanDiego)

Updated:        02/18/07    original version
                09/14/08    fixed offset
                01/03/09    lower band function formula error correction
                01/04/09    future projections added (FutureOffset = 1 or 2)
                04/30/09    clean up and tighten code
                05/29/09    add display of input parameters on chart
                07/08/09    _BarsDisplayed function modified to minimize increase in MaxBarsBack
                            cause by back referencing to print chart labels after LastBarOnChart
                            reached.
                07/10/09    WVAP added as to centerline functions   
               
************************************************************************************** 
                { Reference Function (Center line) May be: }       
                0-Zero axis
                1-AMA (Arithmetic Average)
                2-EMA (Exponential Moving Average
                3-LR (Linear Regression)
                4-Adaptive Moving Avg (Kaufman - KAMA)
                5-T3 Triple Exponential Moving Average
                6-JMA Juric Moving Average or
                7-WVAP
                8-Fixed Value

                { Deviation Function (Band or Ribbons) may be: }
                1-Standard Deviation (Bollinger Bands)
                2-Standard Error
                3-ATR (Average True Range - Keltner Bands)
                4 JMA True Range (ATR using Jurik Moving Avg)
                5-Pct (Percentage)
                6-Points
**************************************************************************************
}
                   
[LegacyColorValue = true];
INPUT:RefID(6), DevID(3);

Inputs:     
    Price(C),
    Smooth(0),

    UpperBandsRef(H),
    LowerBandsRef(L),
    Offset(0),

    //RefID(3),
    AMALength(13),                  { arithmetic moving average length }
    EMALength(13),                  { exponential moving average length }
    LRLength(13),                   { linear regression function length }
    LRTgtBar(0),                    { linear regression function target bar }
    RefValue(0),

    //DevID(1),                        { deviation function identifier }
    StdDevLength(13),                { standard deviation length }
    StdErrLength(13),                { standard error length }
    ATRLength(13),                   { average true range length }
    jthma_ATRLength(13),                  { percentage }
    Percent(1),                         
    Pts(1),
   DoubleS_Length(13),

    NBands(3),                       { maximum 8 }
    StartMult(1),
    Increment(1),
    AddMinus(0),
    RoundToTradable(False),
   
    PlotWidth(4),
    ShowCenterLine(FALSE),
    DisplayParameters(false),         { display chart parameters }
    CLParamColor(yellow),            { center line parameters display color }
    DevParamColor(cyan),             { deviation parameters display color }
    CLVertPct(8),                    { vertical position in chart range percent for center line parameter display }
    DevVertPct(3),                   { vertical position in chart range percent for deviation parameter display }
    CLHorizPct(50),                  { horizontal position in percent for center line parameter display
                                       [leftmost = zero %, rightmost = 100%] }
    DevHorizPct(50);                 { horizontal position in percent for deviation parameter display
                                       [leftmost = zero %, rightmost = 100%] }

Arrays:
    UpperBand[9](0),
    LowerBand[9](0),
    RefParam[4](0),                  { reference function (center line) parameters }
    DevParam[4](0);                  { deviation function (bands or ribbons) parameters }

Variables:     
    UpperCL(0),
    LowerCL(0),
   
    { chart display parameters }
    intrabarpersist string Text1("Center Line:     "),       
    intrabarpersist string Text2("    Deviation:     "),
    intrabarpersist TextVertPct1(CLVertPct),
    intrabarpersist TextVertPct2(DevVertPct),
    intrabarpersist TextHorizPct1(CLHorizPct),
    intrabarpersist TextHorizPct2(DevHorizPct),
    intrabarpersist TextVert1(0),
    intrabarpersist TextVert2(0),
    intrabarpersist int TextOffset1(0),
    intrabarpersist int TextOffset2(0),
    intrabarpersist DisplayHigh(0),
    intrabarpersist DisplayLow(0),
    intrabarpersist DisplayRange(0),
    intrabarpersist BarsDisplayed(0),
    intrabarpersist TextID1(0),
    intrabarpersist TextID2(0),
    intrabarpersist RangePctAtOffset(0),
    intrabarpersist TextLength1(0),
    intrabarpersist TextLength2(0),
    intrabarpersist TextMaxLength(0);

//plot99(c);
{ pack reference and deviation function parameters into arrays }

Once begin
       
    { initialize display parameters text strings }
           

    { Reference function parameters }
    RefParam[0] = RefID;
    switch RefID begin
        Case 0:
            RefParam[1] = 0;
            Text1 = Text1 & "Zero axis";
        Case 1:
            RefParam[1] = AMALength;
            Text1 = Text1 & "AMA " & NumToStr(AMALength, 0);
        Case 2:
            RefParam[1] = EMALength;
            Text1 = Text1 & "EMA " & NumToStr(EMALength, 1);               
        Case 3:
            RefParam[1] = LRLength;
            RefParam[2] = LRTgtBar;
            Text1 = Text1 & "LinReg " & NumToStr(LRLength, 0)
                & "  Offset " & NumToStr(Offset,0) & "  TgtBar " & NumToStr(LRTgtBar, 0);
          end;

    { Deviation function parameters }
    DevParam[0] = DevID;
    switch DevID begin
        Case 1:
            DevParam[1] = StdDevLength;
            Text2 = Text2 & "Std Dev " & NumToStr(StdDevLength, 0);
        Case 2:
            DevParam[1] = StdErrLength;
            Text2 = Text2 & "Std Err " & NumToStr(StdErrLength, 0);
       

    end;


    TextID1 = Text_New(0, 0, 0, Text1);
    TextID2 = Text_New(0, 0, 0, Text2);
    value1 = Text_SetColor(TextID1, CLParamColor);
    value2 = Text_SetColor(TextID2, DevParamColor);

    TextLength1 = StrLen(Text1);
    TextLength2 = StrLen(Text2);
    TextMaxLength = MaxList(TextLength1, TextLength2);

end;
   


    Value1 = _RibbonsCalc_MYWAY(UpperBandsRef[Offset], LowerBandsRef[Offset], RefParam, DevParam,
                NBands, StartMult, Increment, AddMinus, RoundToTradable, UpperBand, LowerBand);

     { PLOTTING }
    If NBands >= 1 Then Begin
        Plot8((UpperBand[1]),"Hi-1");
        Plot10((LowerBand[1]),"Lo-1");

        If NBands >=2 Then Begin
            Plot7((UpperBand[2]),"Hi-2");
            Plot11((LowerBand[2]),"Lo-2");
               
            If NBands >=3 Then Begin
                Plot6((UpperBand[3]),"Hi-3");
                Plot12((LowerBand[3]),"Lo-3");
 
                If NBands >= 4 Then Begin
                    Plot5((UpperBand[4]),"Hi-4");
                    Plot13((LowerBand[4]),"Lo-4");

                    If NBands >= 5 Then Begin
                        Plot4((UpperBand[5]),"Hi-5");
                        Plot14((LowerBand[5]),"Lo-5");
                                             
                        If NBands >=6 Then Begin
                            Plot3((UpperBand[6]), "Hi-6");
                            Plot15((LowerBand[6]),"Lo-6");
                                           
                            If NBands >=7 Then Begin
                                Plot2((UpperBand[7]),"Hi-7");
                                Plot16((LowerBand[7]),"Lo-7");
                       
                                If NBands >=8 Then Begin
                                    Plot1((UpperBand[8]),"Hi-8");
                                    Plot17((LowerBand[8]),"Lo-8");
                                End;
                            End;
                        End;
                    End;
                End;
            End;
        End;   
    End;


    if ShowCenterLine then begin
        Plot9(UpperBand[0] + AddMinus,"URef", default, default, PlotWidth);
        If LowerBand[0] <> UpperBand[0] Then Plot18(LowerBand[0] + AddMinus,"LRef", default, default, PlotWidth);
    end;


    if Smooth > 0 then Plot21(Average(Price, Smooth), "Smooth Price");
    //if Smooth > 0 then Plot21(JRC.JMA.2k(Price, Smooth,0), "Smooth Price");
   

    { chart label section }
    { adding this section causes ribbon plotter to delay plotting for first 200 bars }
    { may wish to comment out this section if using ribbon plotter for strategy testing }
    { since almost 200 more bars of data will be available to analyze }         

    BarsDisplayed = _BarsDisplayed;

    if _LastBarOnChart then begin
       
        if DisplayParameters then begin

            switch RefID begin
                case 0, 7:
                    value1 = _DisplayRangeAll( DisplayHigh, DisplayLow, DisplayRange );

                default:
                    DisplayHigh = Highest(MaxList(UpperBand[NBands], High), BarsDisplayed);
                    DisplayLow = Lowest(MinList(LowerBand[NBands], Low), BarsDisplayed);
                    DisplayRange = DisplayHigh - DisplayLow;
            end;
           
            TextOffset1 = BarsDisplayed * (1 - TextHorizPct1 / 100) + TextMaxLength/2;
            TextOffset2 = BarsDisplayed * (1 - TextHorizPct2 / 100) + TextMaxLength/2;

            { determine range percent of price at middle of text string }
            RangePctAtOffset = (Close[(TextOffset1 + TextOffset2 - TextMaxLength)/2] - DisplayLow) / DisplayRange; 

            if RangePctAtOffset > 0.50 then begin
                TextVert1 = DisplayLow + DisplayRange * TextVertPct1 / 100;
                TextVert2 = DisplayLow + DisplayRange * TextVertPct2 / 100;
            end else begin
                TextVert1 = DisplayHigh - DisplayRange * TextVertPct2 / 100;
                TextVert2 = DisplayHigh - DisplayRange * TextVertPct1 / 100;
            end;

            value3 = Text_SetLocation(TextID1, Date[TextOffset1], Time[TextOffset1], TextVert1);
            value4 = Text_SetLocation(TextID2, Date[TextOffset2], Time[TextOffset2], TextVert2);
        end;   
    end;
{}
   
// debug:
//print(_DateTimeSymbol,TextID1,TextID2,TextOffset1,TextOffset2,DisplayLow,DisplayHigh,DisplayRange,TextVert1,TextVert2);


Return to “User Contributed Studies and Indicator Library”