TOS Strategy Backtesting help

Learnbot

Active member
VIP
Good evening,

I have a question that is above my scripting skills, so I have a treading strategy based on one of the VIP indicators, the issue is with the exit part. I want to enter with VIP indicator signal (which i have figured out) but the exit I want to set based on the entry price. Here is my entry code:

Code:
input tradeSize = 100;
AddOrder(OrderType.BUY_TO_OPEN, IN, close[0], tradeSize, Color.CYAN, Color.CYAN);

Now what I want to happen is exit if the entry price drops down by 2% or goes up by 2%, basically 1 to 1 risk-reward. I have the exit code mapped out too but I just down know how to get the entry price to calculate out 2% win or loss for exit, here is my broken exit strategy code:

Code:
AddOrder(OrderType.SELL_TO_CLOSE, **Idk**, close[0], tradeSize, Color.MAGENTA, Color.MAGENTA);

any help would be very helpful,

Thank you for your time and happy holidays
 

BenTen

Administrative
Staff
VIP
Take a look at this example:

Code:
input length = 20;
input trendSetup = 3;

def BodyMax = Max(open, close);
def BodyMin = Min(open, close);
def IsEngulfing = BodyMax > BodyMax[1] and
    BodyMin < BodyMin[1];
def IsWhite = open < close;
def IsBlack = open > close;
def IsPrevDoji = IsDoji(length)[1];

def Bullish = IsDescending(close, trendSetup)[1] and
    (IsBlack[1] or IsPrevDoji) and
    IsWhite and
    IsEngulfing;

def sell_condition = if Bullish then close else sell_condition[1];
def sell_location = (2/100) * sell_condition;

input tradeSize = 100;

def IN = Bullish;
def OUT = sell_condition - sell_location;
AddOrder(OrderType.BUY_TO_OPEN, IN, close[1], tradeSize, Color.CYAN, Color.CYAN);
AddOrder(OrderType.Sell_TO_CLOSE, OUT, close[1], tradeSize, Color.CYAN, Color.CYAN);

plot data = OUT; 
data.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
data.SetDefaultColor(Color.YELLOW);
 
Last edited:

Learnbot

Active member
VIP
Hi Ben, thank you for the prompt reply, however, the issue is I don't have an exit strategy. My exit strategy is based on the entry price. So lets say my strategy generates a buy signal and at that time the stock price is 100$ I buy 100 shares at 100$, stop loss is set to $98 and profit-taking is at 102$.

so what I want to do is figure out what my entry price is (AddOrder(OrderType.BUY_TO_OPEN, IN, close[0], tradeSize, Color.CYAN, Color.CYAN)) and then build my exit strategy based on the entry price.

I looked into TOS's Entryprice() function but I cant seem to understand how to make it work.

so basically my exit condition would be either one of these conditions:

def Target = Entryprice() + (entryprice()*0.02)
Def Stoploss = Entryprice() - (entryprice()*0.02)
 

rad14733

Well-known member
VIP
@Learnbot Your Target and Stoploss code looks correct... All you need to do is use it in your AddOrder()... The condition for your exit would be along the lines of close crosses above Target or close crosses below Stoploss OR close => Target or close <= Stoploss... Either will work...

Ruby:
AddOrder(OrderType.SELL_TO_CLOSE, close => Target or close <= Stoploss, tradeSize, Color.CYAN, Color.CYAN);
 

Learnbot

Active member
VIP
@rad14733 Thank you so much for your help, however, it doesn't seem to be working. I think the issue is with my "Entrypriec()" function, I am not sure how to use that function and Thinkscript website wasn't making much sense to me lol. Here is my complete code with your suggested fix:

Code:
def price = close;
def superfast_length = 9;
def fast_length = 14;
def slow_length = 21;
def displace = 0;

def mov_avg9 = ExpAverage(price[-displace], superfast_length);
def mov_avg14 = ExpAverage(price[-displace], fast_length);
def mov_avg21 = ExpAverage(price[-displace], slow_length);

#moving averages
def Superfast = mov_avg9;
def Fast = mov_avg14;
def Slow = mov_avg21;

def buy = mov_avg9 > mov_avg14 and mov_avg14 > mov_avg21 and low > mov_avg9;
def stopbuy = mov_avg9 <= mov_avg14;
def buynow = !buy[1] and buy;
def buysignal = CompoundValue(1, if buynow and !stopbuy then 1 else if buysignal[1] == 1 and stopbuy then 0 else buysignal[1], 0);

def Buy_Signal = buysignal[1] == 0 and buysignal == 1;

#Alert(condition = buysignal[1] == 0 and buysignal == 1, text = "Buy Signal", sound = Sound.Bell, "alert type" = Alert.BAR);

def Momentum_Down = buysignal[1] == 1 and buysignal == 0;

#Alert(condition = buysignal[1] == 1 and buysignal == 0, text = "Momentum_Down", sound = Sound.Bell, "alert type" = Alert.BAR);

def sell = mov_avg9 < mov_avg14 and mov_avg14 < mov_avg21 and high < mov_avg9;
def stopsell = mov_avg9 >= mov_avg14;
def sellnow = !sell[1] and sell;
def sellsignal = CompoundValue(1, if sellnow and !stopsell then 1 else if sellsignal[1] == 1 and stopsell then 0 else sellsignal[1], 0);

def Sell_Signal = sellsignal[1] == 0 and sellsignal;

#Alert(condition = sellsignal[1] == 0 and sellsignal == 1, text = "Sell Signal", sound = Sound.Bell, "alert type" = Alert.BAR);

def Momentum_Up = sellsignal[1] == 1 and sellsignal == 0;

#Alert(condition = sellsignal[1] == 1 and sellSignal == 0, text = "Momentum_Up", sound = Sound.Bell, "alert type" = Alert.BAR);

def Colorbars = if buysignal == 1 then 1 else if sellsignal == 1 then 2 else if buysignal == 0 or sellsignal == 0 then 3 else 0;

#___________________________________________________________________________

input method = {default average, high_low};
def bubbleoffset = .0005;
def percentamount = .01;
def revAmount = .05;
def atrreversal = 2.0;
def atrlength = 5;
def pricehigh = high;
def pricelow = low;
def averagelength = 5;
def averagetype = AverageType.EXPONENTIAL;
def mah = MovingAverage(averagetype, pricehigh, averagelength);
def mal = MovingAverage(averagetype, pricelow, averagelength);
def priceh = if method == method.high_low then pricehigh else mah;
def pricel = if method == method.high_low then pricelow else mal;
def EI = ZigZagHighLow("price h" = priceh, "price l" = pricel, "percentage reversal" = percentamount, "absolute reversal" = revAmount, "atr length" = atrlength, "atr reversal" = atrreversal);
def reversalAmount = if (close * percentamount / 100) > Max(revAmount < atrreversal * reference ATR(atrlength), revAmount) then (close * percentamount / 100) else if revAmount < atrreversal * reference ATR(atrlength) then atrreversal * reference ATR(atrlength) else revAmount;
rec EISave = if !IsNaN(EI) then EI else GetValue(EISave, 1);
def chg = (if EISave == priceh then priceh else pricel) - GetValue(EISave, 1);
def isUp = chg >= 0;
rec isConf = AbsValue(chg) >= reversalAmount or (IsNaN(GetValue(EI, 1)) and GetValue(isConf, 1));
def EId = if isUp then 1 else 0;
#plot EnhancedLines = if EId <= 1 then EI else Double.NaN;
#EnhancedLines.AssignValueColor(if EId == 1 then Color.GREEN else if EId == 0 then Color.RED else Color.DARK_ORANGE);
#EnhancedLines.SetStyle(Curve.FIRM);
#EnhancedLines.EnableApproximation();
#EnhancedLines.HideBubble();
#Price Change between Enhanceds
def xxhigh = if EISave == priceh then priceh else xxhigh[1];
def chghigh = priceh - xxhigh[1];
def xxlow = if EISave == pricel then pricel else xxlow[1];
def chglow = pricel - xxlow[1];
def showBubbleschange = no;
#AddChartBubble(showBubbleschange and !IsNaN(EI) and BarNumber() != 1, if isUp then priceh * (1 + bubbleoffset) else pricel * (1 - bubbleoffset) , "$" + chg , if isUp and chghigh > 0 then Color.GREEN else if isUp and chghigh < 0 then Color.RED else if isUp then Color.YELLOW else if !isUp and chglow > 0 then Color.GREEN else if !isUp and chglow < 0 then Color.RED else Color.YELLOW, isUp);
#Price at High/Low
def showBubblesprice = no;
#AddChartBubble(showBubblesprice and !IsNaN(EI) and BarNumber() != 1, if isUp then priceh * (1 + bubbleoffset) else pricel * (1 - bubbleoffset) , if isUp then "$" + priceh else "$" + pricel , if isUp and chghigh > 0 then Color.GREEN else if isUp and chghigh < 0 then Color.RED else if isUp then Color.YELLOW else if !isUp and chglow > 0 then Color.GREEN else if !isUp and chglow < 0 then Color.RED else Color.YELLOW, isUp);
#Label for Confirmed/Unconfirmed Status of Current Enhanced

#Bar Count between Enhanceds
rec EIcount = if EISave[1] != EISave then 1 else if EISave[1] == EISave then EIcount[1] + 1 else 0;
def EIcounthilo = if EIcounthilo[1] == 0 and (EISave == priceh or EISave == pricel) then 1 else if EISave == priceh or EISave == pricel then EIcounthilo[1] + 1 else EIcounthilo[1];
def EIhilo = if EISave == priceh or EISave == pricel then EIcounthilo else EIcounthilo + 1;
def EIcounthigh = if EISave == priceh then EIcount[1] else Double.NaN;
def EIcountlow = if EISave == pricel then EIcount[1] else Double.NaN;
def showBubblesbarcount = no;
#AddChartBubble(showBubblesbarcount and !IsNaN(EI) and BarNumber() != 1, if isUp then priceh * (1 + bubbleoffset) else pricel * (1 - bubbleoffset) , if EISave == priceh then EIcounthigh else EIcountlow, if isUp and chghigh > 0 then Color.GREEN else if isUp and chghigh < 0 then Color.RED else if isUp then Color.YELLOW else if !isUp and chglow > 0 then Color.GREEN else if !isUp and chglow < 0 then Color.RED else Color.YELLOW, if isUp then yes else no );
#Arrows
def EIL = if !IsNaN(EI) and !isUp then pricel else GetValue(EIL, 1);
def EIH = if !IsNaN(EI) and isUp then priceh else GetValue(EIH, 1);
def dir = CompoundValue(1, if EIL != EIL[1] or pricel == EIL[1] and pricel == EISave then 1 else if EIH != EIH[1] or priceh == EIH[1] and priceh == EISave then -1 else dir[1], 0);
def signal = CompoundValue(1, if dir > 0 and pricel > EIL then if signal[1] <= 0 then 1 else signal[1] else if dir < 0 and priceh < EIH then if signal[1] >= 0 then -1 else signal[1] else signal[1], 0);
def showarrows = yes;
def U1 = showarrows and signal > 0 and signal[1] <= 0;
#U1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
#U1.SetDefaultColor(Color.GREEN);
#U1.SetLineWeight(4);
def D1 = showarrows and signal < 0 and signal[1] >= 0;
#D1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
#D1.SetDefaultColor(Color.RED);
#D1.SetLineWeight(4);
def barnumber = BarNumber()[10];

#AddChartBubble((barnumber and U1), if isUp then low else high, if showarrows and signal > 0 and signal[1] <= 0 then "Reversal:" + low else "" , if Colorbars == 3 then Color.PLUM else Color.UPTICK, no);
#AddChartBubble((barnumber and D1), if isUp then low else high, if showarrows and signal < 0 and signal[1] >= 0 then "Reversal:" + high else "" , if Colorbars == 3 then Color.PLUM else Color.DOWNTICK, yes);

def revLineTop;
def revLineBot;

if barnumber and D1 {
revLineBot = Double.NaN;
revLineTop = high[1];
} else if barnumber and U1 {
revLineTop = Double.NaN;
revLineBot = low[1];
} else if !IsNaN(revLineBot[1]) and (Colorbars[2] == 2 or Colorbars[1] == 2) {
revLineBot = revLineBot[1];
revLineTop = Double.NaN;
} else if !IsNaN(revLineTop[1]) and (Colorbars[2] == 1 or Colorbars[1] == 1) {
revLineTop = revLineTop[1];
revLineBot = Double.NaN;
} else {
revLineTop = Double.NaN;
revLineBot = Double.NaN;
}

def botLine = revLineBot[-1];
#botLine.SetDefaultColor(Color.LIGHT_GREEN);
def topLine = revLineTop[-1];
#topLine.SetDefaultColor(Color.LIGHT_RED);

def bullish2 = signal > 0 and signal[1] <= 0;
def upArrow = bullish2;
#################



input tradeSize = 100;



AddOrder(OrderType.BUY_TO_OPEN, uparrow, close[0], tradeSize, Color.CYAN, Color.CYAN);


def Target = Entryprice() + (entryprice()*0.02);
Def Stoploss = Entryprice() - (entryprice()*0.02);


AddOrder(OrderType.SELL_TO_CLOSE, close >= target or close <= stoploss, close[0], tradeSize, Color.MAGENTA, Color.MAGENTA);
 

generic

Active member
@Learnbot This is what I use. Replace buycondition with your actual entry condition.

Code:
def entryprice = if buycondition then close else entryprice[1];

AddOrder(OrderType.SELL_TO_CLOSE, close >= (entryprice + target) or close <= (entryprice - SL), close[0], tradeSize, Color.MAGENTA, Color.MAGENTA);
 

Learnbot

Active member
VIP
@generic No go buddy, something isnt adding up on the code. It's ok though, i just want to check which strategies work the best with which RR is the main goal but I guess I am not understanding the coding section lol. Thank you guys for ur help, any suggestion will help. i would upload the images to show the stoploss or targets are not being hit correctly but I cant upload the image for some reason ( I did try ben's step by step instructions)
 

generic

Active member
@Learnbot I just tried it with your code and it works. The "target" in my code is different from your code so change "target" to some number.

Code:
AddOrder(OrderType.SELL_TO_CLOSE, close >= (entryprice + .25) or close <= (entryprice - .10), close[0], tradeSize, Color.MAGENTA, Color.MAGENTA);

EDIT: Nevermind I see what you mean.
EDIT2: Okay, so it works but depends on your chart timeframe, 1.02*entryprice might be high enough that it won't hit therefore it will never sell but the code I posted does work.
 
Last edited:

MerryDay

Well-known member
VIP
@Learnbot
I can't imagine why your Imgur uploads are not working. But here is another image upload site that maybe won't have the same problems?
https://postimages.org/

After uploading my image, I copy the link labeled: Hotlink for forums then I paste that link directly into my post. HTH

 

Learnbot

Active member
VIP
@Learnbot I just tried it with your code and it works. The "target" in my code is different from your code so change "target" to some number.

Code:
AddOrder(OrderType.SELL_TO_CLOSE, close >= (entryprice + .25) or close <= (entryprice - .10), close[0], tradeSize, Color.MAGENTA, Color.MAGENTA);
You are correct, if I had an exact number than ur suggestion would work like a charm however the issue is entryprice plus xyz number changes because that number is based on the entry price.
sorry to make it super complicated, but i know I am not explaining the exact thing I’m trying to do. Let me try and explain it a little better

so I have a buy condition based on ben’s script, let’s say if condition A meets then I place an order Aka
Code:
input tradeSize = 100;
AddOrder(OrderType.BUY_TO_OPEN, IN, close[0], tradeSize, Color.CYAN, Color.CYAN);

so the code above buys 100 shares at specific price correct? So my biggest issue is I need a script that tells TOS what that price is because my exit strategy is based on risk reward.

so let’s say the above code bought 100 shares at 100$ per share, I want the exit order to trigger IF the current bar’s close is either $102 (target) or price falls down to $98 (stop loss).

(my stop loss is basically risk reward scenario, I’m risking 2% to make 2%)

hope this clarifies what I’m trying to do And the reason I’m doing this is because not all strategies provide 1 to 1 or 1 to 2 or so on risk rewards, some strategies produce better winning percentage if the RR is correct for that specific strategy.
 

generic

Active member
@Learnbot I tested it with your 2% and it works. There some problems with it because of multiple uparrow signals before sell, ext hour, and lower time frames. This is what the bottom of my code looks like, the 3 line of addlabel code can be removed since I was just using them for checking the code. I tested it with SPY, TSLA, and AMD.

Code:
input tradeSize = 100;

def entryprice = if uparrow then close else entryprice[1];


AddOrder(OrderType.BUY_TO_OPEN, uparrow, close[0], tradeSize, Color.CYAN, Color.CYAN);


def Target = entryprice + (entryprice*0.02);
Def Stoploss = entryprice - (entryprice*0.02);

addlabel(yes, entryprice);
addlabel(yes, target);
addlabel(yes, stoploss);
AddOrder(OrderType.SELL_TO_CLOSE, close >= target or close <= stoploss, close[0], tradeSize, Color.MAGENTA, Color.MAGENTA);
 

rad14733

Well-known member
VIP
@Learnbot Yeah, no reason why the code I posted shouldn't work unless there were other reasons... Code syntax is correct so it just needs proper criteria to fire...
 

irishgold

Member
function entryprice() must be defined by itself.
As an example: myEntry = entryPrice();
now you can manipulate myEntry anyway you like.
you cannot reference entryPrice until you define it.
 

Similar threads

Top