AddOrder thinkScript - Backtest Auto Buy & Sell in ThinkorSwim

diazlaz

Well-known member
2019 Donor
VIP
This thread demonstrates how you can use the AddOrder logic to create your own ThinkorSwim backtesting script. It also contains requests and code examples made by other members—worth looking over.

Hi Everyone,

Inspired by @RobertPayne and this post, for a while, I been trying to replicate the auto functionality in the AddOrder. Seems the behavior is different when from Auto and Manual on how AddOrder is executed.

I'm trying to simulate the buy and sell and simulate the reversal from going long to short or vice-versa in the same bar. Auto it seems the entry is taken at the same bar while manual is on the next bar.

Let's use this as an example:

YvfBUdf.png


Ruby:
def EMA = ExpAverage(close, 8);
def STATE = if close > ema then 100 else -100;
plot EMA8 = EMA;

AssignPriceColor (
if STATE == 100 then COLOR.GREEN else COLOR.RED);

AddOrder(OrderType.BUY_AUTO,no);

In this example, if close > ema then go long else go short, if you're in a long trade and trend changes, reverse and go short, vice-versa.

1) Using Auto:

Ruby:
def EMA = ExpAverage(close, 8);
def STATE = if close > ema then 100 else -100;
plot EMA8 = EMA;

AssignPriceColor (
if STATE == 100 then COLOR.GREEN else COLOR.RED);

AddOrder(OrderType.BUY_AUTO,no);

##Automatic
AddOrder(OrderType.BUY_AUTO, condition = (STATE == 100),  name = "BAUTO: " + BarNumber());
AddOrder(OrderType.SELL_AUTO, condition = (STATE == -100),  name = "SAUTO: " + BarNumber());

mrrSK4Q.png


This works as expected, notice that is opening and closing the position at the same bar with a buy to open and a sell to close, vice-versa.

2) Using Manual

Ruby:
def EMA = ExpAverage(close, 8);
def STATE = if close > ema then 100 else -100;
plot EMA8 = EMA;

AssignPriceColor (
if STATE == 100 then COLOR.GREEN else COLOR.RED);

##Long
AddOrder(OrderType.BUY_TO_OPEN, condition = (STATE == 100),  name = "BTO: " + BarNumber());
AddOrder(OrderType.SELL_TO_CLOSE, condition = (STATE == -100),  name = "STC: " + BarNumber());

##Short
AddOrder(OrderType.SELL_TO_OPEN, condition = (STATE == -100),  name = "STO: " + BarNumber());
AddOrder(OrderType.BUY_TO_CLOSE, condition = (STATE == 100),  name = "BTC: " + BarNumber());

The behavior is different, it executes in the next bar as such:

wVMuAnH.png


The reason, is i'm trying to build a strategy that will reverse on trend, but at times, I will pause getting into new positions, but want to close the position when trend change occurs BUT entire in the direction of the trend when that condition is cleared.

Any suggestions or ideas would be greatly appreciated.
 
Last edited by a moderator:

kalivibe

New member
VIP
Thanks for all your help. I have another question regarding strategy exits. Again, just learning. I am trying to exit when the first of two actions occurs. When I use this looking for just one parameter it works properly.

Code:
input barexit = 2;
def LongExt= LongEnt from barexit bars ago;
AddOrder(OrderType.SELL_TO_CLOSE, LongExt, high, TradeSize);

Where LongEnt is also already defined.

However when I try this, I don't get an error but it seems like half of the trades are no longer there?

Code:
input TargetRatio = 1.015;
input barexit = 2;
def LongTarget = LongEnt * TargetRatio;
def LongExt= LongTarget or LongEnt from barexit bars ago;
AddOrder(OrderType.SELL_TO_CLOSE, LongExt, close, TradeSize);

Any help would be great!

Is EntryPrice() known by thinkscript? Also can I change (close >= LongTarget) to (high >= LongTarget)? Would I need to change the Sell to close code as well then?
 

kalivibe

New member
VIP
Thanks!! Really appreciate it. Sorry for all newbie questions. Is changing the following OK?

(close >= LongTarget) to (high >= LongTarget)?

Would I need to change the Sell to close code as well then?
 

YungTraderFromMontana

Well-known member
I have the credentials for what I want to trigger the orders in the strategy but am a novice at coding and can't figure out how to create the automatic orders. All I need is code where I can quickly plug in my credentials for when a order takes place. (ex buy put when , sell put when).

I finally have the signals and orders on my strategy finished but now want to backtest it. Ideally it would allow me to fine tune my strategy by showing me an updating P/L. When I would make a change in the strategy, there would also be a change in the results. This could allow me to perfect my strategy and squeeze every possible dollar or cut every preventable loss. Any feedback will be helpful in passing this final step so thanks everyone.
 

kalivibe

New member
VIP
Hi - I am still struggling to get this to work. I am trying to basically put in a target and if that is not after bars exit. With the code below it always exits after 2 bars only. Any advice would be great. Thanks.

Code:
def TradeSize =100;
input TargetRatio = 1.015;
input TargetRatioShort = .015;
input barexit = 2;
def LongEnt = UpsideBreakout and high[-1] > high;
def LongTarget = EntryPrice () * TargetRatio;
def LongExt= (high >= LongTarget) or (LongEnt from barexit bars ago);

AddOrder(OrderType.BUY_TO_OPEN, LongEnt, high, TradeSize);

AddOrder(OrderType.SELL_TO_CLOSE, LongExt, close, TradeSize);
def ShortEnt= DownsideBreakout and low[-1] < low;
def ShortTarget = EntryPrice ()  - (TargetRatioShort * EntryPrice ());

def ShortExt = ShortTarget or ShortEnt from barexit bars ago;

AddOrder(OrderType.SELL_TO_OPEN, ShortEnt, low, TradeSize);

AddOrder(OrderType.BUY_TO_CLOSE, ShortExt, close, TradeSize);

Wondering if there is anyone that would help me with some programming for payment? I have indicators I have created that I use for entry. I would like to test them using various exit methods . . . taking partial profit at an ATR based target, exiting remainder with a ATR trail stop or based on an indicator.
 

kalivibe

New member
VIP
Thanks. Here is an example. Right now this exits after 2 bars. However I would like to create the exits I described above additionally. Very, very new to attempting to program.

Code:
def RBup = close > open and high < high[1]  and high[1] < high[2] and low < low[1] and close[1] < open[1] and high[-1] > high;
plot bullish = if RBup then high else Double.NaN;
bullish.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
alert(bullish,"RB Up", alert.Bar,sound.ding);
def RBdown = close < open and low > low[1]  and low[1] > low[2] and high > high[1] and close[1] > open[1] and low[-1] < low;
plot bearish = if RBdown then low else Double.NaN;
bearish.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
alert(bearish,"RB Down", alert.Bar, sound.ding);

def TradeSize =100;
input barexit = 2;
def LongEnt = RBup;
def LongExt= LongEnt from barexit bars ago;

AddOrder(OrderType.BUY_TO_OPEN, LongEnt, high, TradeSize);

AddOrder(OrderType.SELL_TO_CLOSE, LongExt, high, TradeSize);
def ShortEnt= RBdown;
def ShortExt = ShortEnt from barexit bars ago;

AddOrder(OrderType.SELL_TO_OPEN, ShortEnt, low, TradeSize);

AddOrder(OrderType.BUY_TO_CLOSE, ShortExt, low, TradeSize);
 

Miket

Member
How do you guys backtest a strategy on ThinkorSwim? I'd like to take a look at the results for the Sequence Counter found in TOS.
 

tomsk

Well-known member
VIP
How do you guys backtest a strategy on ThinkorSwim? I'd like to take a look at the results for the Sequence Counter found in TOS.

@Miket You can backtest any studies by using the Strategy functionality on TOS.
Here is a very simple example of a strategy
Bullish when price closes above the 34 EMA and bearish when prices closes below the 34 EMA

Code:
input length = 34;
input price = close;

plot EMA = ExpAverage(price, length);
EMA.AssignValueColor(if EMA > EMA[1]
                     then Color.Green
                     else Color.Red);
AssignPriceColor(if EMA > EMA[1]
                 then Color.Green
                 else Color.Red);
AddOrder(OrderType.BUY_AUTO, EMA crosses above EMA[1]);
AddOrder(OrderType.Sell_AUTO, EMA crosses below EMA[1]);

To see the results of your strategy, position your mouse on any of the strategy points on your chart
Right click the mouse and select "Show report"
You will then see a table of your buy/sell strategy with date of trade, price as well as P/L from that strategy
 

msammons

Member
In OnDemand TOS back testing is it possible to use an if statement for an AddOrder?

Something that would, for example, sell short every cross-below but buy long every cross-above (and closes trade when it crosses the other way): all in one TOS strategy

Something like:

def cross-above= cross above EMA;
def cross-below = cross below EMA;

if cross-above then AddOrder(OrderType.BUY_TO_OPEN, cross-above, open[-1], 100) else if cross-below then AddOrder(OrderType.SELL_TO_OPEN, cross-below, open[-1], 100) else no;
if close > EMA then AddOrder(OrderType.SELL_TO_CLOSE, cross-below, open[-1], 100) else if close < EMA then AddOrder(OrderType.BUY_TO_CLOSE, cross-above, open[-1], 100) else no;
 

tomsk

Well-known member
VIP
Don't think that is a valid syntax and from all the different AddOrder statements I have seen, it is generally used without any if-then-else construct. Probably best to vary the condition upon which a buy/sell order is triggered, so if the condition is not triggered, no buy/sell order is effected.
 
Last edited:

dvorakm

New member
2019 Donor
VIP
I am trying to test out a strategy, but the sell orders are not behaving (selling at wrong time) and therefore jacking with the open orders. Could someone please help me with a command to test out the buying only part of a strategy? That is, implement only the buying portion of the strategy so I can test and refine that portion.

When I comment out the "sell" potion, I only get one "buy" order, because it is expecting a sell to close. What I am trying to do is bypass that and have multiple buy orders triggered by the strategy, ignoring the "sell" part. Then, I would be able to refine the selling part of the script so that it sells at the correct time.
 

gwbabcock

New member
One way to do it is to keep your logic out of AddOrder statement. Here is an example:

Code:
input EMALenShort = 9;
input EMALenLong = 20;

def EMAPlus = (MovAvgExponential(close, EMALenShort) - MovAvgExponential(close, EMALenLong)) >= 0;

AddOrder(OrderType.BUY_AUTO, EMAPlus,   open[1],  tickcolor = GetColor(0), arrowcolor = GetColor(0),name = "BAuto: " + BarNumber());
AddOrder(OrderType.SELL_AUTO, !EMAPlus,   open[1],  tickcolor = GetColor(1), arrowcolor = GetColor(1),name = "SAuto: " + BarNumber());

Also note BUY_AUTO and SELL_AUTO will automatically switch when EMAPlus goes from positive to negative and vv.
 

john3

Active member
2019 Donor
Regardless of a strategy, how would I limit the backtest only to the regular trading hours (RTH)? I trade futures and always have an overnight session displayed, but for a backtest I only would like to test the RTH.

In addition, also regardless of a strategy, but let's say it is a simple MAs cross, I would like to know an average price move after a signal has been triggered. For example, 10 SMA crossing 20 SMA both ways (up/down), the strategy enters on the next bar open after the cross, what is an average price move after the cross? It would be great if after the cross it would automatically plot a line with a user-selectable target. For example, after the cross, plot a line 2 point away from the cross.

Appreciate your help!
 

BenTen

Administrative
Staff member
Staff
VIP
Lifetime
@john3 You can try to apply the same method @WalkingBallista did in his code here.

Code:
def MarketOpenTime = 0930;
input TimeToStopSignal = 1525;
def TradeTimeFilter = SecondsFromTime(TimeToStopSignal);

Use that condition to only allow signals between market open and 1525 (which is 3:25 EST). Take a look at the full code in the post I linked. It should help.
 
R

RickAns

Guest
Hi All,

What a great site this is. I am really learning a lot about thinkscript.

Is it possible to use different tradeSize values for multiple AddOrder commands within a Strategy?

For example, if I want to open a trade with 20 shares and when a trailing stop is hit to sell 5 shares. Leaving me still holding 15 shares. No matter what I try with "tradeSize = " it insists on selling the entire 20 from the first buy and closing out the position. What am I not doing correctly, or is this hard coded into thinkorswim?

Can provide more examples if needed. I have discovered how for thinkorswim to let me do multiple buys in a row - thanks to BenTen for a picture of that in someone else's post. Just currently trying to figure out how to do a partial sell (or buy, on a pullback) with AddOrder. I am working on this to use with the Floating Profit / Loss function.

Thanks in advance,
Rick
 
You can use something like this:

Code:
input tradeSize = 20;
input partialExit = 5;

AddOrder(OrderType.BUY_TO_CLOSE, condition = closePartial, price = close, tradesize = partialExit, tickcolor = Color.WHITE, arrowcolor = Color.White, name = "Partial Exit");

"closePartial" would be a condition you define to trigger the partial close.

You may be having issues if you are using the preloaded thinkscript "TrailingStopLX" or "TrailingStopSX" strategies. If you are using those separate from your custom strategy, they will default to the Default Trade Size under the Global Strategy Settings.

To get around this, you need to write the trailing stop code into your custom strategy and reference tradeSize from within the strategy. Some cutting and pasting should get you there.
 
Last edited:

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Top