Hi @Astroidor
It seems the exact formula for StochasticFull() is not public but it should be close to the following:
_SECTION_BEGIN("StochRSI");
RSI_length = Param("RSI length", 14, 2, 100, 1);
over_bought = Param("overbought level", 80, 5, 95, 5);
over_sold = Param("oversold level", 20, 5, 95, 5);
RSI_average_type = ParamList("RSI Avg Type", "SMA|EMA|WMA|Wilders|DEMA", 3);
RSI_price = ParamField("RSI price");
KPeriod = Param("K period", 14, 2, 100);
DPeriod = Param("P period", 3, 1, 100);
slowing_period = Param("slowing period", 1, 1, 20);
averageType = ParamList("average type", "SMA|EMA", 0);
showBreakoutSignals = ParamList("show breakout signals", "No|On FullK|On FullD|On FullK FullD");
function RSIx(price, length, type) {
local D, Up, Dn, MUp, MDn;
D = price - Ref(price,-1);
Up = IIf(D > 0, D, 0);
Dn = IIf(D < 0, -D, 0);
switch(type) {
case "SMA": MUp = MA(Up, length); MDn = MA(Dn, length); break;
case "EMA": MUp = EMA(Up, length); MDn = EMA(Dn, length); break;
case "WMA": MUp = WMA(Up, length); MDn = WMA(Dn, length); break;
case "Wilders": MUp = Wilders(Up, length); MDn = Wilders(Dn, length); break;
case "DEMA": MUp = WMA(Up, length); MDn = WMA(Dn, length); break;
default: MUp = MDn = 0;
}
return 100*SafeDivide(MUp, (MUp+MDn), 0.5);
}
// https://tlc.thinkorswim.com/center/reference/Tech-Indicators/studies-library/R-S/StochasticFull
// NB: in AFL only few params are used in each function. You could use profiles:
// function StochasticFullK(k, R) and function StochasticFullD(k, d, R) and function StochasticFullSlow(k, d, R, slow, type)
// Even better, pass StochasticFullK result as a param to StochasticFullD to fasten computation:
// function StochasticFullK(k, R), function StochasticFullD(d, StochFK), function StochasticFullSlow(StochFD, slow, type)
// I've kept the same profile to help AFL beginners make the translation from TOS and study AFL.
function StochasticFullK(P, ob, os, k, d, R, slow, type) {
local Lk, Hk;
Lk = LLV(R, k); Hk = HHV(R, k);
return 100*SafeDivide((R - Lk), (Hk - Lk), 0.5);
}
function StochasticFullD(P, ob, os, k, d, R, slow, type) {
local SK, SD;
SK = StochasticFullK(P, ob, os, k, d, R, slow, type);
SD = MA(SK, d);
return SD;
}
function StochasticFullSlow(P, ob, os, k, d, R, slow, type) {
local S, SD;
SD = StochasticFullD(P, ob, os, k, d, R, slow, type);
switch(type) {
case "SMA": S = MA(SD, slow); break;
case "EMA": S = EMA(SD, slow); break;
default: S = MA(SD, slow); break;
}
return S;
}
// Indicators
RSIb = RSIx(RSI_price, RSI_length, RSI_average_type);
FullK = StochasticFullK(RSI_price, over_bought, over_sold, KPeriod, DPeriod, RSIb, slowing_period, averageType);
FullD = StochasticFullD(RSI_price, over_bought, over_sold, KPeriod, DPeriod, RSIb, slowing_period, averageType);
Plot(RSIb, "RSI", colorYellow);
PlotGrid(over_bought, colorGreen); PlotGrid(over_sold, colorRed);
Plot(FullK, "FullK", colorlightBlue, styleThick);
Plot(FullD, "FullD", colorOrange, styleThick);
// System
upK = Cross(FullK, over_sold);
upD = Cross(FullD, over_sold);
downK = Cross(over_bought, FullK);
downD = Cross(over_bought, FullD);
switch (showBreakoutSignals) {
case "No": Buy = Short = 0; break;
case "On FullK": Buy = upK; Short = downK; break;
case "On FullD": Buy = upD; Short = downD; break;
case "On FullK FullD":
Buy = upK OR upD; Short = downK OR downD; break;
default: Buy = Short = 0; break;
}
Sell = Short; Cover = Buy;
shape = Buy * shapeUpArrow + Short * shapeDownArrow;
PlotShapes( shape, IIf( Buy, colorGreen, colorRed ), 0, IIf( Buy, over_sold, over_bought ) );
_SECTION_END();
/*
TOS Code:
declare lower;
input RSI_length = 14;
input over_bought = 80;
input over_sold = 20;
input RSI_average_type = AverageType.WILDERS;
input RSI_price = close;
input KPeriod = 14;
input DPeriod = 3;
input slowing_period = 1;
input averageType = AverageType.SIMPLE;
input showBreakoutSignals = {default "No", "On FullK", "On FullD", "On FullK &
FullD"};
def RSI = RSI(price = RSI_price, length = RSI_length, averageType =
RSI_average_type);
plot FullK = StochasticFull(over_bought, over_sold, KPeriod, DPeriod, RSI, RSI, RSI,
slowing_period, averageType).FullK;
plot FullD = StochasticFull(over_bought, over_sold, KPeriod, DPeriod, RSI, RSI, RSI,
slowing_period, averageType).FullD;
plot OverBought = over_bought;
plot OverSold = over_sold;
def upK = FullK crosses above OverSold;
def upD = FullD crosses above OverSold;
def downK = FullK crosses below OverBought;
def downD = FullD crosses below OverBought;
plot UpSignal;
plot DownSignal;
switch (showBreakoutSignals) {
case "No":
UpSignal = Double.NaN;
DownSignal = Double.NaN;
case "On FullK":
UpSignal = if upK then OverSold else Double.NaN;
DownSignal = if downK then OverBought else Double.NaN;
case "On FullD":
UpSignal = if upD then OverSold else Double.NaN;
DownSignal = if downD then OverBought else Double.NaN;
case "On FullK & FullD":
UpSignal = if upK or upD then OverSold else Double.NaN;
DownSignal = if downK or downD then OverBought else Double.NaN;
}
*/
You can learn AFL by comparing both formulas.
Merry christmas & Happy new year