I have a question. Would it be possible to make this ribbonsplotter indicator for MT4? Sorry for the long thing, could'nt attach the txt file.
Thx.
D.
Code: Select all
// Method DisplayParam() requires 2X number of bars that are shown on screen to be loaded on chart. Otherwise, will not calc correctly.
// May be simpler to just specific vertical value for the two labels, and input an offset for the text of each label to start.
{
Indicator: _RibbonsPlotter
Description: This Indictor plots various types of ribbons (multiple bands of deviation functions)
around a centerline reference function.
Provided By: 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 to centerline functions
08/15/09 _RibbonsCalc function modified. Band calculations done within this indicator
rather than within _RibbonsCalc, as strategies will also use _RibbonCalc
and strategies do not need calculation of ribbon arrays.
04/11/10 added capability estimate next bar value of center line based on
center line rate of change and acceleration. This useful when used in conjuntion
with strategies that generate orders in Buy/Sell Next Bar at [value] format.
06/02/11 Remove Jurik functions for forum posting.
07/16/11 Replace function RibbonsCalc with local Method RibbonsCalc. This avoids the added
complexity of sending a large number of parameters to function RibbonsCalc.
01/01/12 offset calculation error corrected
01/01/12 replace plotting code with Method PlotRibbons()
02/26/12 include offset with JMA centerline calculation
12/08/12 Error in label positioning on chart corrected.
01/15/13 Improve labelling code.
01/16/13 Add real time intrabar re-calculations
01/28/13 Add display parameter offset
02/23/13 Modify display parameters.
08/06/13 Modifying position of display parameters to right justify against chart edge.
11/02/13 Fixed bug with linear regression centerlines not recognizing the TargetBar input parameter
_____________________________________________________________________________________________________________
{ 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(close),
Smooth(0),
UpperBandsRef(avgprice),
LowerBandsRef(avgprice),
Offset(1),
RefID(3),
AMALength(15), { arithmetic moving average length }
EMALength(15), { exponential moving average length }
LRLength(300), { linear regression function length }
LRTgtBar(0), { linear regression function target bar. Use negative Value1 to project into future. }
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(5),
JMAPhase(0),
VWAP_("No Param RefID = 7"),
RefValue(0),
DevID(2), { deviation function identifier }
StdDevLength(0), { standard deviation length }
StdErrLength(0), { standard error length }
ATRLength(14), { average true range length }
JATRLength(14), { percentage }
Percent(1),
Pts(1),
NBands(5), { maximum 8 }
StartMult(0.7),
Increment(0.95),
AddMinus(0),
RoundToTradable(true),
PlotWidth(0),
ShowCenterLine(true),
ShowCenterLineTrendColor(false), { color centerline indicating direction of trend }
DisplayParameters(true), { display chart parameters }
RefTextHeightPct(30), { Reference Text info vertical height % }
DevTextHeightPct(20), { Deviation Text info vertical height % }
DisplayParamOffset(4), { Display parameters offset }
CLTextColor(yellow), { center line parameters text display color }
DevTextColor(cyan), { deviation parameters text display color }
RefVertPct(8), { vertical position in chart range percent for center line parameter display }
DevVertPct(3), { vertical position in chart range percent for deviation parameter display }
int CalcSeconds(10);
Arrays:
UpperBand[9](0),
LowerBand[9](0);
Vars:
intrabarpersist UpperCL(0),
intrabarpersist LowerCL(0),
intrabarpersist UpperDev(0),
intrabarpersist LowerDev(0),
Intrabarpersist DevLength(0),
n(0),
x(0),
{ function LinearRegFaster variables }
oLRSlope( 0),
oLRAngle( 0),
oLRIntercept(0), { left intercept, value of beginning of LR line (at offset of [ Length - 1 ] bars }
oLRValueRaw(0),
{ _StdDevMean variables }
oMean(0),
{ chart display parameters }
Intrabarpersist BS(0),
Intrabarpersist LastBar(false),
Intrabarpersist Calc(false),
intrabarpersist string Text1(""),
intrabarpersist string Text2(""),
intrabarpersist TextID1(0),
intrabarpersist TextID2(0),
intrabarpersist TextVertPct1(RefVertPct), { percentage of range to display Text1 }
intrabarpersist TextVertPct2(DevVertPct), { percentage of range to display Text1 }
intrabarpersist TextVert1(0), { vertical Value1 at which to Display Text1 }
intrabarpersist TextVert2(0), { vertical Value1 at which to Display Text2 }
intrabarpersist DisplayHigh(0),
intrabarpersist DisplayLow(0),
intrabarpersist DisplayRange(0), { vertical Range of chart }
Intrabarpersist MidRange(0), { vertical middle of charting }
// intrabarpersist TextLength1(0),
// intrabarpersist TextLength2(0),
// intrabarpersist TextLengthMax(0),
{ variables for method RibbonCalc }
{ if StdDevLength or StdErrLength = 0, then set length same as linear regression center line length (LRLength) }
SDLength(MaxList(iff(StdDevLength > 2, StdDevLength, LRLength), 2)), { standard deviation requires minimum length of 2 }
SELength(MaxList(iff(StdErrLength > 3, StdErrLength, LRLength), 3)); { standard error requires minimum length of 3 }
var: elsystem.Timer Timer1( NULL );
Method override void InitializeComponent()
begin
Timer1 = new elsystem.Timer;
Timer1.Interval = CalcSeconds * 1000;
Timer1.AutoReset = true;
Timer1.Enable = true;
Timer1.Name = "Timer1";
Timer1.elapsed += Timer1_Elapsed;
end;
{ run once every CalcSeconds seconds}
Method void Timer1_Elapsed( elsystem.Object sender, elsystem.TimerElapsedEventArgs args )
begin
//BS = -1; { all timer generated executions associated with BarStatus(1) = -1 (undefined) }
Calc = true;
end;
Method void RibbonsCalc()
begin
{ ESTABLISH CENTERLINE }
switch RefID begin
Case 0:
UpperCL = UpperBandsRef[Offset];
case 1:
UpperCL = AverageFC(UpperBandsRef[Offset], AMALength);
case 2:
UpperCL = _XAverage.Simple(UpperBandsRef[Offset], EMALength);
case 3:
Value1 = _LinearRegFaster(UpperBandsRef[Offset], LRLength, LRTgtBar, oLRSlope, oLRAngle, oLRIntercept, UpperCL );
case 4:
UpperCL = _KAMA(UpperBandsRef[Offset], KAMA_EffRatioLen, KAMA_FastLength, KAMA_SlowLength);
case 5:
UpperCL = T3Average.Simple(UpperBandsRef[Offset], T3Length);
{
{comment out next 2 lines if Juric moving average not installed }
case 6:
UpperCL = JRC.JMA.2k(UpperBandsRef[offset], JMALength, JMAPhase);
}
case 7:
UpperCL = _VWAP;
case 8:
UpperCL = RefValue;
end;
if LowerBandsRef = UpperBandsRef then begin
LowerCL = UpperCL;
end else begin
switch RefID begin
Case 0:
LowerCL = LowerBandsRef[Offset];
case 1:
LowerCL = AverageFC(LowerBandsRef[Offset], AMALength);
case 2:
LowerCL = _XAverage.Simple(LowerBandsRef[Offset], EMALength);
case 3:
Value1 = _LinearRegFaster(LowerBandsRef[Offset], LRLength, LRTgtBar, oLRSlope, oLRAngle, oLRIntercept, LowerCL );
case 4:
LowerCL = _KAMA(LowerBandsRef[Offset], KAMA_EffRatioLen, KAMA_FastLength, KAMA_SlowLength);
case 5:
LowerCL = T3Average.Simple(LowerBandsRef[Offset], T3Length);
{
{ comment out the next two lines if Jurik functions are not installed }
case 6:
LowerCL = JRC.JMA.2k(LowerBandsRef[Offset], JMALength, JMAPhase);
}
case 7:
LowerCL = _VWAP[Offset];
case 8:
LowerCL = RefValue;
end;
end;
{ ESTABLISH FUNCTION }
switch DevID begin
case 1:
value1 = _StdDevMean(UpperBandsRef[Offset], SDLength, 1, oMean, UpperDev);
Case 2:
UpperDev = _StdError(UpperBandsRef[Offset], SELength);
case 3:
UpperDev = _AvgTrueRange(ATRLength)[Offset];
{
{ comment out the next two lines if Jurik functions are not installed }
case 4:
UpperDev = _JMATrueRange(JATRLength)[Offset];
}
case 5:
UpperDev = UpperBandsRef[Offset] * Percent / 100;
case 6:
UpperDev = Pts;
end;
if LowerBandsRef = UpperBandsRef then begin
LowerDev = UpperDev;
end else begin
switch DevID begin
case 1:
value1 = _StdDevMean(LowerBandsRef[Offset], SDLength, 1, oMean, LowerDev);
Case 2:
LowerDev = _StdError(LowerBandsRef[Offset], SELength);
case 3:
LowerDev = UpperDev;
case 4:
LowerDev = UpperDev;
case 5:
LowerDev = LowerBandsRef[Offset] * Percent / 100;
case 6:
LowerDev = Pts;
end;
end;
end; { Method RibbonCalc }
Method void LoadBandsArray()
begin
{ ROUND OFF to tradeable value }
if RoundToTradable then begin { with rounding }
for n = 1 to NBands begin
x = StartMult + (n - 1) * Increment;
UpperBand[n] = Round2Fraction(UpperCL + x * UpperDev + AddMinus);
LowerBand[n] = Round2Fraction(LowerCL - x * LowerDev + AddMinus);
end;
UpperBand[0] = Round2Fraction(UpperCL);
LowerBand[0] = Round2Fraction(LowerCL);
end else begin { no rounding off }
for n = 1 to NBands begin
x = StartMult + (n - 1) * Increment;
UpperBand[n] = UpperCL + x * UpperDev + AddMinus;
LowerBand[n] = LowerCL - x * LowerDev + AddMinus;
end;
UpperBand[0] = UpperCL;
LowerBand[0] = LowerCL;
End;
end; { Method LoadBandsArray }
Method void InitializeTextLabels()
begin
{ Reference function parameters }
switch RefID begin
Case 0:
Text1 = "Center Line: " & "Zero axis";
Case 1:
Text1 = "Center Line: " & "AMA " & NumToStr(AMALength, 0);
Case 2:
Text1 = "Center Line: " & "EMA " & NumToStr(EMALength, 1);
Case 3:
Text1 = "Center Line: " & "LinReg " & NumToStr(LRLength, 0)
& " Offset " & NumToStr(Offset,0) & " oTgtBar " & NumToStr(LRTgtBar, 0);
Case 4:
Text1 = "Center Line: " & "KAMA " & NumToStr(KAMA_EffRatioLen, 1)
& ", " & NumToStr(KAMA_FastLength, 1) & ", " & NumToStr(KAMA_SlowLength, 1);
Case 5:
Text1 = "Center Line: " & "T3 " & NumToStr(T3Length, 0);
Case 6:
Text1 = "Center Line: " & "JMA " & NumToStr(JMALength, 0) & " Phase " & NumToStr(JMAPhase, 0);
Case 7:
Text1 = "Center Line: " & "VWAP";
Case 8:
Text1 = "Center Line: " & "Value = " & NumToStr(RefValue, 1);
end; { switch RefID }
{ Deviation function parameters }
switch DevID begin
Case 1:
{ if no length specified, use length of reference function }
Text2 = "Deviation: " & "Std Dev " & NumToStr(SDLength, 0) & " Mult: " & NumToStr(StartMult,1);
Case 2:
{ if no length specified, use length of reference function }
Text2 = "Deviation: " & "Std Err " & NumToStr(SELength, 0) & " Mult: " & NumToStr(StartMult,1);
Case 3:
Text2 = "Deviation: " & "ATR " & NumToStr(ATRLength, 0) & " Mult: " & NumToStr(StartMult,1);
Case 4:
Text2 = "Deviation: " & "JURIC ATR " & NumToStr(JATRLength, 0) & " Mult: " & NumToStr(StartMult,1);
Case 5:
Text2 = "Deviation: " & "Percent " & NumToStr(Percent, 1) & " Mult: " & NumToStr(StartMult,1);
Case 6:
Text2 = "Deviation: " & "Points " & NumToStr(Pts, 2) & " Mult: " & NumToStr(StartMult,1);
end; { switch DevID }
TextID1 = Text_New(0, 0, 0, Text1);
TextID2 = Text_New(0, 0, 0, Text2);
value1 = Text_SetColor(TextID1, CLTextColor);
value2 = Text_SetColor(TextID2, DevTextColor);
Value1 = Text_SetStyle(TextID1, 1, 2) ; { center vertically and horizontally }
Value1 = Text_SetStyle(TextID2, 1, 2) ; { center vertically and horizontally }
{
TextLength1 = StrLen(Text1);
TextLength2 = StrLen(Text2);
TextLengthMax = MaxList(TextLength1, TextLength2) + DisplayParamOffset;
}
end; { Method InitializeTextLabels }
Method void DisplayParam()
begin
DisplayHigh = GetAppInfo( aiHighestDispValue ) ;
DisplayLow = GetAppInfo( aiLowestDispValue ) ;
DisplayRange = DisplayHigh - DisplayLow;
MidRange = (DisplayHigh + DisplayLow)/2;
{ Place label away from price action }
If Close > MidRange then begin
TextVert1 = DisplayLow + 0.01 * TextVertPct1 * DisplayRange;
TextVert2 = DisplayLow + 0.01 * TextVertPct2 * DisplayRange;
End else begin
TextVert1 = DisplayHigh - 0.01 * TextVertPct2 * DisplayRange;
TextVert2 = DisplayHigh - 0.01 * TextVertPct1 * DisplayRange;
end;
Text_SetLocation(TextID1, Date[DisplayParamOffset], Time[DisplayParamOffset], TextVert1) ;
Text_SetLocation(TextID2, Date[DisplayParamOffset], Time[DisplayParamOffset], TextVert2) ;
end; { Method DisplayParam }
Method void PlotRibbons()
begin
{ 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(UpperCL[0], "URef", default, default, PlotWidth);
If LowerCL[0] <> UpperCL[0] Then Plot18(LowerCL[0], "LRef", default, default, PlotWidth);
end;
if ShowCenterLineTrendColor then begin
if (UpperBand[0] - UpperBand[0][1]) >= 0 then
SetPlotColor[1](9, green)
else
SetPlotColor[1](9, red);
if LowerBand[0] <> UpperBand[0] then begin
if (LowerBand[0] - LowerBand[0][1]) >= 0 then
SetPlotColor[1](18, green)
else
SetPlotColor[1](18, red);
end;
end;
if Smooth > 0 then Plot21(Average(Price, Smooth), "Smooth Price");
// if Smooth > 0 then Plot21(JRC.JMA.2k(Price, Smooth,0), "Smooth Price"); // may use this line if Jurik Moving Average functions are installed
end; { Method PlotRibbons }
#region Main Program
BS = BarStatus(1);
once(_LastBarOnChart) begin
LastBar = true;
end;
Switch BS begin
Case 1:
#region Every Tick Processing
#region Triggered Calculations
{ Calculate immediately at start of real time data }
once Calc = true;
{ ReCalculate and Plot once every CalcSeconds during real time data }
If Calc then begin
#region Calculate Ribbons
RibbonsCalc();
#endregion
{ load center line and deviations into arrays }
#region Load Bands Array
LoadBandsArray();
#endregion
#region PlotRibbons
PlotRibbons();
#endregion
#region Display Parameter info
if DisplayParameters and LastBar then begin
DisplayParam();
end;
#endregion
Calc = false;
end;
#endregion; { Triggered Calculations }
#endregion { Tick Processing }
Case 2:
#region EndOfBar Processing
Once InitializeTextLabels();
#region Calculate Ribbons
RibbonsCalc();
#endregion
{ load center line and deviations into arrays }
#region Load Bands Array
LoadBandsArray();
#endregion
#region PlotRibbons
PlotRibbons();
#endregion
#endregion { EndOfBar Processing }
#region LastBar Processing
#region Display Parameter info
if DisplayParameters and LastBar then begin
DisplayParam();
end;
#endregion
#endregion
end;
#endregion { Main Program }