#BonBon - Heiken_Ashi based on Sylvan Verboort's Trading with HA Candlestick Oscillator
#Bon Bon _last update 2/1/2021, Jan 17th 2021,
#Influenced by script from HoboTheClown / blt,http://www.thinkscripter.com, TD Hacolt etc., Thinkscript Cloud, #TOS & Thinkscript Collection
#Code adapted by @rlohmeyer for chart signals
input candleSmoothing = {default Valcu, Vervoort};
input MA_Type1 = {default TEMA, Hull, ExpAverage};
input t1_period = 34;
input MA_Type2 = {default TEMA, Hull, ExpAverage};
input t2_period = 34;
input swing_back = 20;
input swing_forward = 34;
#Code 1
def openMA;
def closeMA;
def highMA;
def lowMA;
#Code2
def openMA2;
def closeMA2;
def highMA2;
def lowMA2;
#Code1
switch (MA_Type1) {
case Hull:
openMA = CompoundValue(1, HullMovingAvg(open, t1_period), open);
closeMA = CompoundValue(1, HullMovingAvg(close, t1_period), close);
highMA = CompoundValue(1, HullMovingAvg(high, t1_period), high);
lowMA = CompoundValue(1, HullMovingAvg(low, t1_period), low);
case TEMA:
openMA = CompoundValue(1, TEMA(open, t1_period), open);
closeMA = CompoundValue(1, TEMA(close, t1_period), close);
highMA = CompoundValue(1, TEMA(high, t1_period), high);
lowMA = CompoundValue(1, TEMA(low, t1_period), low);
case ExpAverage:
openMA = CompoundValue(1, ExpAverage (open, t1_period), open);
closeMA = CompoundValue(1, ExpAverage(close, t1_period), close);
highMA = CompoundValue(1, ExpAverage(high, t1_period), high);
lowMA = CompoundValue(1, ExpAverage(low, t1_period), low);
}
#Code2
switch (MA_Type2) {
case Hull:
openMA2 = CompoundValue(1, HullMovingAvg(open, t2_period), open);
closeMA2 = CompoundValue(1, HullMovingAvg(close, t2_period), close);
highMA2 = CompoundValue(1, HullMovingAvg(high, t2_period), high);
lowMA2 = CompoundValue(1, HullMovingAvg(low, t2_period), low);
case TEMA:
openMA2 = CompoundValue(1, TEMA(open, t2_period), open);
closeMA2 = CompoundValue(1, TEMA(close, t2_period), close);
highMA2 = CompoundValue(1, TEMA(high, t2_period), high);
lowMA2 = CompoundValue(1, TEMA(low, t2_period), low);
case ExpAverage:
openMA2 = CompoundValue(1, ExpAverage (open, t2_period), open);
closeMA2 = CompoundValue(1, ExpAverage(close, t2_period), close);
highMA2 = CompoundValue(1, ExpAverage(high, t2_period), high);
lowMA2 = CompoundValue(1, ExpAverage(low, t2_period), low);
}
#Code1
def haopen;
def haclose;
switch (candleSmoothing){
case Valcu:
haOpen = CompoundValue(1, ( (haOpen[1] + (openMA[1] + highMA[1] + lowMA[1] + closeMA[1]) / 4.0) / 2.0), open);
haClose = ((((openMA + highMA + lowMA + closeMA) / 4.0) + haOpen + Max(highMA, haOpen) + Min(lowMA, haOpen)) / 4.0);
case Vervoort:
haOpen = CompoundValue(1, ( (haOpen[1] + (openMA[1] + highMA[1] + lowMA[1] + closeMA[1]) / 4.0 ) / 2.0), open);
haClose = ((((openMA + highMA + lowMA + closeMA) / 4.0) + haOpen + Max(highMA, haOpen) + Min(lowMA, haOpen)) / 4.0);
}
def halow = Min(lowMA, haOpen);
def hahigh = Max(highMA, haOpen);
def trend = if haclose >= haopen then 1 else 0; # halow1[-50]
def trendd = if haclose < haopen then 1 else 0;
#Code2
def haopen2;
def haclose2;
switch (candleSmoothing){
case Valcu:
haOpen2 = CompoundValue(1, ( (haOpen2[1] + (openMA2[1] + highMA2[1] + lowMA2[1] + closeMA2[1]) / 4.0) / 2.0), open);
haClose2 = ((((openMA2 + highMA2 + lowMA2 + closeMA2) / 4.0) + haOpen2 + Max(highMA2, haOpen2) + Min(lowMA2, haOpen2)) / 4.0);
case Vervoort:
haOpen2 = CompoundValue(1, ( (haOpen2[1] + (openMA2[1] + highMA2[1] + lowMA2[1] + closeMA2[1]) / 4.0 ) / 2.0), open);
haClose2 = ((((openMA2 + highMA2 + lowMA2 + closeMA2) / 4.0) + haOpen2 + Max(highMA2, haOpen2) + Min(lowMA2, haOpen2)) / 4.0);
}
def halow2 = Min(lowMA2, haOpen2);
def hahigh2 = Max(highMA2, haOpen2);
def trend2 = if haclose2 >= haopen2 then 1 else 0; # halow1[-50]
def trendd2 = if haclose2 < haopen2 then 1 else 0;
#Signals1
#Original code by Taz43
#updated by BonBon 1/15/21 inccreased swing_back periods, changed "high and Low to Halow1 and Hahigh1".
def sb = swing_back;
def sf = swing_forward;
def na = Double.NaN;
def lfor1 = Lowest(halow, sf)[-sf]; #Remember that a negative number inside the square brackets means "after" this bar. So, the above line is defining "lfor" as being the lowest value of the two bars after this bar.
def lback1 = Lowest(halow, sb)[1]; #This line of code is defining "lback" as the lowest value of the eight bars before this one.
def swinglow1 = if halow < lfor1 and halow < lback1 then 1 else 0;
#Finally, this line is actually defining what a "swing low" is. It says, if the low of this bar is lower than the two bars after this one AND the low of this bar is also lower than or equal to the lowest of the previous eight bars, then this bar is a swing low. So, what that means is that in order to determine whether a point on the chart is either a swing high or a swing low, it must have eight bars before the bar in question, as well as, two bars after it. Looking at the picture above, it can be seen that point "A" is a "swing high" because it is higher than the 8 bars before it AND it is higher than the 2 bars after it. Likewise, point "C" is a "swing low" because it is lower than the 8 bars before it AND it is lower than the 2 bars after it. (I know it's a line chart, not a bar chart. smiling smiley Just work with me here.)
def hfor1 = Highest(hahigh, sf)[-sf];
def hback1 = Highest(hahigh, sb)[1];
def swinghigh1 = if hahigh > hfor1 and hahigh > hback1 then 1 else 0;
plot fh = if swinghigh1 then hahigh else na ;
fh.SetDefaultColor(Color.red);
fh.SetPaintingStrategy(PaintingStrategy.booleaN_ARROW_DOWN);
fh.SetLineWeight(1);
plot fl = if swinglow1 then halow else na;
fl.SetPaintingStrategy(PaintingStrategy.boolean_ARROW_UP);
fl.SetDefaultColor(Color.green);
fl.SetLineWeight(1);
#Signals2
def lfor2 = Lowest(halow2, sf)[-sf]; #Remember that a negative number inside the square brackets means "after" this bar. So, the above line is defining "lfor" as being the lowest value of the two bars after this bar.
def lback2 = Lowest(halow2, sb)[1]; #This line of code is defining "lback" as the lowest value of the eight bars before this one.
def swinglow2 = if halow2 < lfor2 and halow2 < lback2 then 1 else 0;
#Finally, this line is actually defining what a "swing low" is. It says, if the low of this bar is lower than the two bars after this one AND the low of this bar is also lower than or equal to the lowest of the previous eight bars, then this bar is a swing low. So, what that means is that in order to determine whether a point on the chart is either a swing high or a swing low, it must have eight bars before the bar in question, as well as, two bars after it. Looking at the picture above, it can be seen that point "A" is a "swing high" because it is higher than the 8 bars before it AND it is higher than the 2 bars after it. Likewise, point "C" is a "swing low" because it is lower than the 8 bars before it AND it is lower than the 2 bars after it. (I know it's a line chart, not a bar chart. smiling smiley Just work with me here.)
def hfor2 = Highest(hahigh2, sf)[-sf];
def hback2 = Highest(hahigh2, sb)[1];
def swinghigh2 = if hahigh2 > hfor2 and hahigh2 > hback2 then 1 else 0;
plot fh2 = if swinghigh2 then hahigh2 else na ;
fh.SetDefaultColor(Color.red);
fh.SetPaintingStrategy(PaintingStrategy.booleaN_ARROW_DOWN);
fh.SetLineWeight(1);
plot fl2 = if swinglow2 then halow2 else na;
fl.SetPaintingStrategy(PaintingStrategy.boolean_ARROW_UP);
fl.SetDefaultColor(Color.green);
fl.SetLineWeight(1);