B-rad
New member
I have managed to learn some thinkscript basics and frankensteined some code together to create a profitable strategy when backtested. My issue is that when I change the backtest into a regular study (with indicators for entry and exit points) it seems that something is lost in translation.
The strategy is a simple one I found on a free youtube video from John Carter involving a regression to the mean, and I have now modified slightly. The three required conditions for an long entry are:
Note how the down arrows are referencing every instance where price is above the upper bollinger band whereas -below in strategies- they only fire after an entry point is signaled.
I have had this same issue with other code on different strategies as well. I don't know, maybe I should have paid more attention to my high school geometry teacher when she was taking about 'If and only if' logical statements..... Any ideas?
The strategy is a simple one I found on a free youtube video from John Carter involving a regression to the mean, and I have now modified slightly. The three required conditions for an long entry are:
- RSI below 30
- Not in a TTM squeeze
- and the current price below the lower bollinger band
#bollingerbands
input price = close;
input displace = 0;
input length = 20;
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;
input averageType = AverageType.SIMPLE;
def sDev = StDev(data = price[-displace], length = length);
def MidLine = MovingAverage(averageType, data = price[-displace], length = length);
def LowerBand = MidLine + Num_Dev_Dn * sDev;
def UpperBand = MidLine + Num_Dev_up * sDev;
#bollingerbandsEND
#RSI
input length2 = 14;
input over_Bought = 70;
input over_Sold = 30;
input price2 = close;
input averageType2 = AverageType.WILDERS;
input showBreakoutSignals = no;
def NetChgAvg = MovingAverage(averageType2, price2 - price2[1], length);
def TotChgAvg = MovingAverage(averageType2, AbsValue(price2 - price2[1]), length);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;
def RSI = 50 * (ChgRatio + 1);
def OverSold = over_Sold;
def OverBought = over_Bought;
def UpSignal = if RSI crosses above OverSold then OverSold else Double.NaN;
def DownSignal = if RSI crosses below OverBought then OverBought else Double.NaN;
#RSI END
#ttmsqueeze start
input price3 = close;
input length3 = 20;
input Num_Dev_Dn3 = -2.0;
input Num_Dev_up3 = 2.0;
input averageType3 = AverageType.SIMPLE;
input displace3 = 0;
def sDev3 = StDev(data = price3[-displace], length = length3);
def MidLineBB = MovingAverage(averageType, data = price3[-displace3], length = length);
def LowerBandBB = MidLineBB + Num_Dev_Dn * sDev3;
def UpperBandBB = MidLineBB + Num_Dev_up * sDev3;
input factorhigh = 1.0;
input factormid = 1.5;
input factorlow = 2.0;
input trueRangeAverageType3 = AverageType.SIMPLE;
def shifthigh = factorhigh * MovingAverage(trueRangeAverageType3, TrueRange(high, close, low), length3);
def shiftMid = factormid * MovingAverage(trueRangeAverageType3, TrueRange(high, close, low), length);
def shiftlow = factorlow * MovingAverage(trueRangeAverageType3, TrueRange(high, close, low), length);
def average = MovingAverage(averageType, price3, length3);
def Avg = average[-displace];
def UpperBandKCLow = average[-displace] + shiftlow[-displace];
def LowerBandKCLow = average[-displace] - shiftlow[-displace];
def UpperBandKCMid = average[-displace] + shiftMid[-displace];
def LowerBandKCMid = average[-displace] - shiftMid[-displace];
def UpperBandKCHigh = average[-displace] + shifthigh[-displace];
def LowerBandKCHigh = average[-displace] - shifthigh[-displace];
def K = (Highest(high, length3) + Lowest(low, length3)) /
2 + ExpAverage(close, length3);
def momo = Inertia(price3 - K / 2, length3);
def pos = momo >= 0;
def neg = momo < 0;
def up = momo >= momo[1];
def dn = momo < momo[1];
def presqueeze = LowerBandBB > LowerBandKCLow and UpperBandBB < UpperBandKCLow;
def originalSqueeze = LowerBandBB > LowerBandKCMid and UpperBandBB < UpperBandKCMid;
def ExtrSqueeze = LowerBandBB > LowerBandKCHigh and UpperBandBB < UpperBandKCHigh;
def PosUp = pos and up;
def PosDn = pos and dn;
def NegDn = neg and dn;
def NegUp = neg and up;
def squeezeline = 0;
def momentum = momo;
#ttmsqueezeEND
Def longEntryPoint = if !presqueeze and !originalsqueeze and !extrsqueeze and (price <= lowerband) and (price > oversold) then 1 else 0;
Def longExitPoint = price >= upperband;
plot Longentry = if longentrypoint and !longentrypoint[1] then 1 else 0;
Longentry.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
Plot Longexit = if longexitpoint then 1 else 0;
Longentry.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
Note how the down arrows are referencing every instance where price is above the upper bollinger band whereas -below in strategies- they only fire after an entry point is signaled.
I have had this same issue with other code on different strategies as well. I don't know, maybe I should have paid more attention to my high school geometry teacher when she was taking about 'If and only if' logical statements..... Any ideas?