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: 7740
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 1033 times
Been thanked: 2221 times

Postby TJ » 13 Mar 2010

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


p.s. please use the

Code: Select all

[/b][/color] 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: 7740
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 1033 times
Been thanked: 2221 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: 7740
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 1033 times
Been thanked: 2221 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: 7740
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 1033 times
Been thanked: 2221 times

Postby TJ » 19 Mar 2010

give this a try.
Attachments
_RibbonsPlotter (TJ-1).txt
(12.79 KiB) Downloaded 684 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: 7740
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 1033 times
Been thanked: 2221 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: 7740
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 1033 times
Been thanked: 2221 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: 7740
Joined: 29 Aug 2006
Location: Global Citizen
Has thanked: 1033 times
Been thanked: 2221 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”