3 Trigger Strategy

B

boogieG

New member
Good evening,

I am trying to test a theory on a strategy but am having some trouble with the code producing the desired results and Im not sure if its because the script is complicated or if Im misunderstanding something about the inputs.

The strategy combines 2 indicators found of this forum. @BenTen 's ORB Breakout indicator found here as well as some components from the scan also posted on that thread: https://usethinkscript.com/threads/opening-range-breakout-indicator-for-thinkorswim.16/. And @horserider 's Ultimate RSI short term indicator found here: https://usethinkscript.com/threads/ultimate-rsi-indicator-for-thinkorswim.411/. It also incorporates the PPS Buy signal. This would be all on the 15 min chart.

The idea is that I want a buy signal when there is an ORB breakout and the ultimate RSI is positive and up for both RSIs and there has been a PPS buy signal within 3 bars of the breakout.

I believe my issue is somewhere with the PPS signal or perhaps not fully understanding the RSI indicator. My code so far is below. I obviously had to omit some of the assigncolor lines as they serve no purpose in the strategy.

Code:
# RSI Bands and Double RSI SMA Cross Short Term Trades
#Created by Horserider 7/20/2019

#RSI
input length = 5;
input over_Bought = 80;
input over_Sold = 20;
input price = close;
input averageType = AverageType.WILDERS;
input line = 50;

def NetChgAvg = MovingAverage(averageType, price - price[1], length);
def TotChgAvg = MovingAverage(averageType, AbsValue(price - price[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 lline = 50;

#                ==== THE FIVE ====

##MY CODE##===========
def RSIUP = RSI >= 50 and RSI > RSI[1];
def RSIDOWN = RSI < 50 and RSI < RSI[1];

# RSI 2
input length2 = 8;
input over_Bought2 = 80;
input over_Sold2 = 20;
input price2 = close;
input averageType2 = AverageType.WILDERS;

def NetChgAvg2 = MovingAverage(averageType2, price2 - price2[1], length2);
def TotChgAvg2 = MovingAverage(averageType2, AbsValue(price2 - price2[1]), length2);
def ChgRatio2 = if TotChgAvg2 != 0 then NetChgAvg2 / TotChgAvg2 else 0;

def RSI2 = 50 * (ChgRatio2 + 1);
def OverSold2 = over_Sold;
def OverBought2 = over_Bought;

##MY CODE##
def RSIUP2 = RSI2 >= 50 and RSI2 > RSI2[1];
def RSIDOWN2 = RSI2 < 50 and RSI2 < RSI2[1];

AddCloud(RSI, RSI2, Color.GREEN, Color.RED);

#plot 5;

input AverageTypeBB = {default SMA, EMA, HMA};
input displaceBB = 0;
input lengthBB = 5;
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;

def upperBand;
def lowerBand;
def midline ;


switch (AverageTypeBB) {
case SMA:
    upperBand = reference BollingerBands(RSI, displaceBB, lengthBB, Num_Dev_Dn, Num_Dev_up).UpperBand;
    lowerBand = reference BollingerBands(RSI, displaceBB, lengthBB, Num_Dev_Dn, Num_Dev_up).LowerBand;
    midline   = reference BollingerBands(RSI, displaceBB, lengthBB, Num_Dev_Dn, Num_Dev_up).Midline;
case EMA:
    upperBand = reference BollingerBands(RSI, displaceBB, lengthBB, Num_Dev_Dn, Num_Dev_up, averageType = AverageType.EXPONENTIAL).UpperBand;
    lowerBand = reference BollingerBands(RSI, displaceBB, lengthBB, Num_Dev_Dn, Num_Dev_up, averageType = AverageType.EXPONENTIAL).LowerBand;
    midline   = reference BollingerBands(RSI, displaceBB, lengthBB, Num_Dev_Dn, Num_Dev_up, averageType = AverageType.EXPONENTIAL).Midline;
case HMA:
    upperBand = reference BollingerBands(RSI, displaceBB, lengthBB, Num_Dev_Dn, Num_Dev_up, averageType = AverageType.EXPONENTIAL).UpperBand;
    lowerBand = reference BollingerBands(RSI, displaceBB, lengthBB, Num_Dev_Dn, Num_Dev_up, averageType = AverageType.EXPONENTIAL).LowerBand;
    midline   = reference BollingerBands(RSI, displaceBB, lengthBB, Num_Dev_Dn, Num_Dev_up, averageType = AverageType.EXPONENTIAL).Midline;
}

def OpenRangeMinutes = 30;
def MarketOpenTime = 0930;
def LastBar = SecondsFromTime(1530) == 0;
input TimeToStopSignal = 1525;
def TradeTimeFilter = SecondsFromTime(TimeToStopSignal);
input ShowTodayOnly = no;
input Limiter = 0.015;
AddVerticalLine(SecondsFromTime(0930) == 0, "Open", Color.GRAY, Curve.SHORT_DASH);
AddVerticalLine(!TradeTimeFilter, "Last Signal", Color.DARK_GRAY, Curve.SHORT_DASH);
def Today = if GetDay() == GetLastDay() then 1 else 0;
def FirstMinute = if SecondsFromTime(MarketOpenTime) < 60 then 1 else 0;
def OpenRangeTime = if SecondsFromTime(MarketOpenTime) < 60 * OpenRangeMinutes then 1 else 0;

def ORHigh =  if FirstMinute then high else if OpenRangeTime and high > ORHigh[1] then high else ORHigh[1];
def ORLow = if FirstMinute then low else if OpenRangeTime and low < ORLow[1] then low else ORLow[1];

def OpenRangeHigh = if ShowTodayOnly and !Today then Double.NaN else if !OpenRangeTime then ORHigh else Double.NaN;
def OpenRangeLow = if ShowTodayOnly and !Today then Double.NaN else if !OpenRangeTime then ORLow else Double.NaN;

def dailyRange = high(period = "day" )[1] - low(period = "day" )[1];

def PreviousRange = high[1] - low[1];
def range = Average(PreviousRange, 10);

def entryLine1 = OpenRangeHigh + (range * 0.06);
def entryLine2 = OpenRangeLow - (range * 0.06);

def breakout = close > (entryLine1 + (entryLine1 * Limiter));
def ppsBuy = PPS().BuySignal is true within 3 bars;
def RSIBuy = RSIUP and RSIUP2;

AddOrder(OrderType.BUY_TO_OPEN, breakout and ppsBuy and RSIBuy);
AddOrder(OrderType.SeLL_TO_CLOSE, RSIDOWN and RSIDOWN2);
 
horserider

horserider

Well-known member
VIP
Where is the PPS code?

Also can eliminate more.
Code:
# RSI Bands and Double RSI SMA Cross Short Term Trades
#Created by Horserider 7/20/2019

#RSI
input length = 5;
input price = close;
input averageType = AverageType.WILDERS;

def NetChgAvg = MovingAverage(averageType, price - price[1], length);
def TotChgAvg = MovingAverage(averageType, AbsValue(price - price[1]), length);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;

def RSI = 50 * (ChgRatio + 1);

##MY CODE##===========
def RSIUP = RSI >= 50 and RSI > RSI[1];
def RSIDOWN = RSI < 50 and RSI < RSI[1];

# RSI 2
input length2 = 8;

input price2 = close;
input averageType2 = AverageType.WILDERS;

def NetChgAvg2 = MovingAverage(averageType2, price2 - price2[1], length2);
def TotChgAvg2 = MovingAverage(averageType2, AbsValue(price2 - price2[1]), length2);
def ChgRatio2 = if TotChgAvg2 != 0 then NetChgAvg2 / TotChgAvg2 else 0;

def RSI2 = 50 * (ChgRatio2 + 1);

##MY CODE##
def RSIUP2 = RSI2 >= 50 and RSI2 > RSI2[1];
def RSIDOWN2 = RSI2 < 50 and RSI2 < RSI2[1];


def OpenRangeMinutes = 30;
def MarketOpenTime = 0930;
def LastBar = SecondsFromTime(1530) == 0;
input TimeToStopSignal = 1525;
def TradeTimeFilter = SecondsFromTime(TimeToStopSignal);
input ShowTodayOnly = no;
input Limiter = 0.015;
AddVerticalLine(SecondsFromTime(0930) == 0, "Open", Color.GRAY, Curve.SHORT_DASH);
AddVerticalLine(!TradeTimeFilter, "Last Signal", Color.DARK_GRAY, Curve.SHORT_DASH);
def Today = if GetDay() == GetLastDay() then 1 else 0;
def FirstMinute = if SecondsFromTime(MarketOpenTime) < 60 then 1 else 0;
def OpenRangeTime = if SecondsFromTime(MarketOpenTime) < 60 * OpenRangeMinutes then 1 else 0;

def ORHigh =  if FirstMinute then high else if OpenRangeTime and high > ORHigh[1] then high else ORHigh[1];
def ORLow = if FirstMinute then low else if OpenRangeTime and low < ORLow[1] then low else ORLow[1];

def OpenRangeHigh = if ShowTodayOnly and !Today then Double.NaN else if !OpenRangeTime then ORHigh else Double.NaN;
def OpenRangeLow = if ShowTodayOnly and !Today then Double.NaN else if !OpenRangeTime then ORLow else Double.NaN;

def dailyRange = high(period = "day" )[1] - low(period = "day" )[1];

def PreviousRange = high[1] - low[1];
def range = Average(PreviousRange, 10);

def entryLine1 = OpenRangeHigh + (range * 0.06);
def entryLine2 = OpenRangeLow - (range * 0.06);

def breakout = close > (entryLine1 + (entryLine1 * Limiter));
def ppsBuy = PPS().BuySignal is true within 3 bars;
def RSIBuy = RSIUP and RSIUP2;

AddOrder(OrderType.BUY_TO_OPEN, breakout and ppsBuy and RSIBuy);
AddOrder(OrderType.SeLL_TO_CLOSE, RSIDOWN and RSIDOWN2);
 
B

boogieG

New member
@horserider I was also unsure about the PPS signal since the source code isnt available but I tried my hand at referencing the buy signal in "def ppsBuy = PPS().BuySignal is true within 3 bars;" as I've seen studies referenced this way in the past. There may be an issue as far as input length for the PPS now that I am looking at it a second time and thinking about how the study works. Would an IsNaN function have to be used for pps? I am not sure if it is a number output or not.
 
horserider

horserider

Well-known member
VIP
@boogieG Yes hidden code makes it difficult. I decided to play a bit and since the PPS is just 2 moving averages I believe you can closely approximate the PPS signals with just doing your own moving average crosses. Simple moving averages of 4 and 7. Put the crosses into your code and that may solve the PPS issue. Feel free to experiment with other types of moving averages if you think you can get a better match. Hmmm why hide what appears to be very simple code.
 
D

diazlaz

Well-known member
2019 Donor
VIP
PPS study is probably a licensed study, a clone was developed by Mobius a while back.

Maybe supplement the code with clone.

Ruby:
Mobius©: # PPS replica

input n  = 2;
input n2 = 7;
input n3 = 5;
input n4 = 4;

def c = close;

plot data  = Average(Inertia(c, n), n2);
plot data2 = ExpAverage(Inertia(ohlc4, n3), n4);

#Stan this is a better statement for the arrows in the PPS:
plot ArrowUP = data crosses above data2 and close crosses above data2;
ArrowUP.SetPaintingStrategy(PaintingStrategy.Boolean_Arrow_UP);

Plot ArrowDN = close crosses below data2 and data crosses below data2;
     ArrowDN.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
 

Similar threads

Top