#// This source code is subject to the terms of the Mozilla Public License 2.0 a
#// © LonesomeTheBlue
#study("Trend Follower", precision=0)
# -- Converted and mod By Sam4Cok@Samer800 - 11/2023
declare lower;
input timeframe = {default "Chart", "Custom"};
input customTimeframe = AggregationPeriod.FIFTEEN_MIN;
input colorBars = yes;
input showSignals = yes;
input showDynamicLevels = yes;
input showSignalLine = yes;
input matype = {default EMA, SMA, RMA, WMA, VWMA}; # "MA Type"
input source = FundamentalType.CLOSE;
input movAvgPeriod = 20; # "MA Period"
input lookbackPeriod = 20; # "Period to Check Trend"
input signalLength = 9; # "Signal Smoothing"
input priceRangeLength = 280;
input TrendChannelRate = 1.0; # "Trend Channel Rate %"
input UseLinearRegression = yes; # "Use Linear Regression"
input LinearRegressionPeriod = 5; # "Linear Regression Period"
def na = Double.NaN;
def last = IsNaN(close);
#-- MTF
def tfC = Fundamental(source);
def tfh = high;
def tfl = low;
def tfv = volume;
def mtfc = Fundamental(FundamentalType = source, Period = customTimeframe);
def mtfh = high(Period = customTimeframe);
def mtfl = low(Period = customTimeframe);
def mtfv = volume(Period = customTimeframe);
def c; def h; def l; def v;
Switch (timeframe) {
case "Custom" :
c = mtfc;
h = mtfh;
l = mtfl;
v = mtfv;
Default :
c = tfc;
h = tfh;
l = tfl;
v = tfv;
}
def rate = TrendChannelRate / 100;
def pricerange = Highest(h , priceRangeLength) - Lowest(l, priceRangeLength);
def chan = pricerange * rate;
Script MovAvg {
input matype = "EMA";
input c = close;
input maprd = 20;
input v = volume;
def clvol = c * v;
def vwma = Average(clvol, maprd) / Average(v, maprd);
def masrc = if matype == "EMA" then ExpAverage(c, maprd) else
if matype == "SMA" then Average(c, maprd) else
if matype == "RMA" then WildersAverage(c, maprd) else
if matype == "WMA" then WMA(c, maprd) else
if matype == "VWMA" then vwma else ExpAverage(c, maprd);
plot out = masrc;
}
# gettrend(len)=>
def masrc = MovAvg(matype, c, movAvgPeriod, v);
def LinReg = Inertia(masrc, LinearRegressionPeriod);
def ma = if UseLinearRegression then LinReg else masrc;
def hh = Highest(ma, lookbackPeriod);
def ll = Lowest(ma, lookbackPeriod);
def diff = AbsValue(hh - ll);
def up = ma > ll + chan;
def dn = ma < hh - chan;
def trd = If(diff > chan, If(up, 1, If(dn, -1, 0)), 0);
def _ret = trd * diff / chan;
def trend = _ret;
def trandchanged = trend - trend[1];
def tcol = if trend > 0 then if trandchanged > 0 then 3 else if trandchanged <= 0 then 1 else 2 else
if trend < 0 then if trandchanged < 0 then -3 else if trandchanged >= 0 then -1 else -2 else 0;
# Fake Filter by © HasanRifat
def signal = MovAvg(matype, trend, signalLength, v);
def hist = trend - signal;
def positiveTop;
def negatieTop;
def activeWave;
#// Trend average wave height calculation
def trendZeroCrossOver = !isNaN(trend[1]) and trend > 0 and trend[1] <= 0;
def trendZeroCrossUnder = !isNaN(trend[1]) and trend < 0 and trend[1] >= 0;
if trendZeroCrossOver {
activeWave = 1;
} else
if trendZeroCrossUnder {
activeWave = -1;
} else {
activeWave = activeWave[1];
}
def dirUp = activeWave == 1;
def dirDn = activeWave == -1;
def AvgHi; def AvgLo; def countUp; def countDn;
if dirUp {
positiveTop = max(positiveTop[1], trend);
negatieTop = 0;
AvgHi = AvgHi[1];
AvgLo = if !dirUp[1] then AvgLo[1] + negatieTop[1] else AvgLo[1];
countUp = countUp[1];
countDn = if !dirUp[1] then countDn[1] + 1 else countDn[1];
} else
if dirDn {
negatieTop = min(negatieTop[1], trend);
positiveTop = 0;
AvgHi = if !dirDn[1] then AvgHi[1] + positiveTop[1] else AvgHi[1];
AvgLo = AvgLo[1];
countUp = if !dirDn[1] then countUp[1] + 1 else countUp[1];
countDn = countDn[1];
} else {
negatieTop = 0;
positiveTop = 0;
AvgHi = AvgHi[1];
AvgLo = AvgLo[1];
countUp = countUp[1];
countDn = countDn[1];
}
def posAvgHi = AvgHi;
def cntUp = countUp;
def positiveAvgHi = posAvgHi / cntUp;
def negAvgHi = AvgLo;
def cntDn = countDn;
def negativeAvgHi = negAvgHi / cntDn;
def bearishCrossunder = (trend < signal) and (trend[1] >= signal[1]);
def bullishCrossover = (trend > signal) and (trend[1] <= signal[1]);
def crossDn = bearishCrossunder and trend > positiveAvgHi;
def crossUp = bullishCrossover and trend < negativeAvgHi;
AddChartBubble(showSignals and crossDn and !crossDn[1], trend[1], "S", Color.RED, YES);
AddChartBubble(showSignals and crossUp and !crossDn[1], trend[1], "B", Color.GREEN, NO);
#-- Plot
plot sgPlot = if showSignalLine then signal else na; # "Signal"
plot psHeight = if last or !showDynamicLevels then na else positiveAvgHi; # "Positive Avg Height"
plot ngHeight = if last or !showDynamicLevels then na else negativeAvgHi; # "Negative Avg Height"
ngHeight.SetDefaultColor(Color.PLUM);
psHeight.SetDefaultColor(Color.VIOLET);
sgPlot.AssignValueColor(if signal > positiveAvgHi then Color.CYAN else
if signal < negativeAvgHi then Color.MAGENTA else Color.YELLOW);
plot trendHist = if tcol != 0 then trend else na;
trendHist.SetPaintingStrategy(PaintingStrategy.SQUARED_HISTOGRAM);
trendHist.AssignValueColor(if tcol == 3 then Color.GREEN else
if tcol == 2 then Color.LIGHT_GREEN else
if tcol == 1 then Color.DARK_GREEN else
if tcol == -1 then Color.DARK_RED else
if tcol == -2 then Color.LIGHT_RED else
if tcol == -3 then Color.RED else Color.GRAY);
plot zeroLine = if last then na else 0;
zeroLine.SetDefaultColor(Color.DARK_GRAY);
AssignPriceColor(if !colorBars then Color.CURRENT else
if crossUp and !crossUp[1] then Color.CYAN else
if crossDn and !crossDn[1] then Color.MAGENTA else
if tcol == 3 then Color.GREEN else
if tcol == 2 then Color.LIGHT_GREEN else
if tcol == 1 then Color.DARK_GREEN else
if tcol == -1 then Color.DARK_RED else
if tcol == -2 then Color.LIGHT_RED else
if tcol == -3 then Color.RED else Color.GRAY);
#-- END of CODE