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:

ItsAl

New member
*I apologize I have very little knowledge regarding coding, so this is a total hack job with various studies/strategies spliced together.

I've been watching market internals very closely in developing my intraday futures trading. I have become obsessed with the relationships between the TICK, ADD, Market Breathe and /VX as it relates to the price action of /ES. Recently I stumbled on a study by Mobius in the Onedrive where he identifies divergences between $ADSPD and /ES, this seems to provide a leading signal for sudden price action as the divergence rights itself.

In playing with this I applied it against the other "internals" to see if there's anything there, well there is!

Here is my chart: https://tos.mx/yyJHDDr

Vw8xawL.jpg


I altered the study as well as incorporated it into a strategy. The /VX divergences seemed to be the most actionable divergence signal, as written the backtest report is pretty crazy.
BqnbQqW.jpg


If someone could help me optimize the order execution code and limiting orders to RTH to help get realistic backtesting I'd really appreciate it! Also any thoughts on how to code entries to capture the $ADSPD impulses would be great! Thanks in advance!
 
Last edited by a moderator:

Jompatan

New member
I have the problem of not knowing how to see if this script is profitable.
It is as simple as buying when the short moving average crosses the long moving average and selling when the opposite occurs.
I don't know if I have set the AddOrder function well.

I know of the existence of the FLOATINGPL study but it shows nothing.
 

Gildes

New member
VIP
Hi guys,

I need your help, I am looking for a base script I could use to test any strategy based on my criteria for Long or short who could
label the Success Rate.

Thank you
 
Last edited by a moderator:

DeftMove

New member
I have something for you, it does require some tweaking though. It also has been the best workaround since TOS does not give WR, only P/L.

The idea is to isolate winning trades as a gain of 1 and losing trades as a loss of 1, regardless of whether it was a big or small loss.

https://tos.mx/SWDW3kQ
Code:
##Template for counting strategies
#Updated: 4.25.2020 by DeftMove - gkc
#Negative and positive winrate represented by DOLLAR AMOUNT P/L in report above/below zero

#PLACE STUDIES HERE


input tradeLot = 1; #hint tradeLot: Number of shares per order.
input analyzeWR = yes; #hint analyzeWR = if YES, dollar amounts P/L in report above/below zero are considered win/loss discrepancy. if NO, dollar amounts P/L in report are considered P/L
input runBuyAnalysis = yes; #hint runBuyAnalysis: if YES, run upward plays, if NO, prevent upward plays
def entryConditionBuy = ; #edit for each strategy, UP ENTRY CONDITIONS
def exitConditionBuy  = ; #edit for each strategy, UP EXIT  CONDITIONS
def exitGoodBuy = open[-1] > EntryPrice();
def exitBadBuy  = open[-1] < EntryPrice();

AddOrder(OrderType.BUY_TO_OPEN, condition = entryConditionBuy and runBuyAnalysis, price = open[-1], tradeLot, name = "BuyOpen " + open[-1]);
AddOrder(OrderType.SELL_TO_CLOSE, runBuyAnalysis and exitConditionBuy and exitGoodBuy, price = if analyzeWR then EntryPrice() + 1 else open[-1], tradeLot, name = "SellClose " + open[-1] + "P/L: " +  (open[-1] - EntryPrice()));
AddOrder(OrderType.SELL_TO_CLOSE, runBuyAnalysis and exitConditionBuy and exitBadBuy, price = if analyzeWR then EntryPrice() - 1 else open[-1], tradeLot, name = "SellClose " + open[-1] + "P/L: " +  (open[-1] - EntryPrice()));

input runSellAnalysis = yes; #hint runSellAnalysis: if YES, run downward plays, if NO, prevent downward plays
def entryConditionSell = ; #edit for each strategy, DOWN ENTRY CONDITIONS
def exitConditionSell = ; #edit for each strategy, DOWN EXIT  CONDITIONS
def exitGoodSell = open[-1] < EntryPrice();
def exitBadSell  = open[-1] > EntryPrice();

AddOrder(OrderType.SELL_TO_OPEN, condition = entryConditionSell and runSellAnalysis, price = open[-1], tradeLot, name = "SellOpen " + open[-1]);
AddOrder(OrderType.BUY_TO_CLOSE, runSellAnalysis and exitConditionSell and exitGoodSell, price = if analyzeWR then EntryPrice() - 1 else open[-1], tradeLot, name = "BuyClose " + open[-1] + "P/L: " + (EntryPrice() - open[-1]));
AddOrder(OrderType.BUY_TO_CLOSE, runSellAnalysis and exitConditionSell and exitBadSell, price = if analyzeWR then EntryPrice() + 1 else open[-1], tradeLot, name = "BuyClose " + open[-1] + "P/L: " + (EntryPrice() - open[-1]));

Your strategy/studies need to generate entry and exit conditions for upward and downward trades for this to work. Place them in the conditions indicated.

Once you click the reports, the default settings will give you a P/L in dollar amounts. Positive amounts mean your strategy has a >50% win rate, negative means it is <50% WR.

Calculate WR by this equation:
[ (#TotalTrades - P/L) / 2 + P/L ] /#TotalTrades

There are toggles for upward or downward trades as well as to switch off WR and show P/L instead. Lastly, if you want more lots traded per order, there is an input for that as well.

Also, please let me know if there could be any improvements. I just started working on this a two days ago after I learned that strategies exist and I doubt my code is streamlined (not a code writer IRL)
 

STB

Member
I am looking for the add order to trigger on the current candle when the volume goes higher than the previous bar, but instead it adds the order to the open of the new candle once it is created.

Code:
AddOrder(OrderType.BUY_TO_OPEN, CLOSE>VWAP and volume>volume[1] , tickColor = GetColor(2), arrowColor = GetColor(2), name = "LE");
 

apollo23

New member
Hi

Found PriceAverageCrossover study in TOS but how do i simulate a buy and sell using this strategy? As it is, the Profit and Loss graph is not showing anything.

Am seeing the arrow signal on the chart but hope to improve it further. These are my thoughts.

Entry:

Previous Open of price must be below moving average and today open is above moving average

Exit Option 1:

Price close below moving average

Exit Option 2:

Price had increase say 30% from entry.

Can anybody help ? Below is the script:

Code:
#
# TD Ameritrade IP Company, Inc. (c) 2009-2020
#

#wizard input: price
#wizard text: crosses
#wizard input: crossingType
#wizard input: averageType
#wizard text: Inputs: length:
#wizard input: length

input price = close;
input length = 15;
input averageType = AverageType.Simple;
input crossingType = {default above, below};

def avg = MovingAverage(averageType, price, length);

plot signal = crosses(price, avg, crossingType == CrossingType.above);

signal.DefineColor("Above", GetColor(6));
signal.DefineColor("Below", GetColor(7));
signal.AssignValueColor(if crossingType == CrossingType.above then signal.color("Above") else signal.color("Below"));

signal.SetPaintingStrategy(if crossingType == CrossingType.above
    then PaintingStrategy.BOOLEAN_ARROW_UP
    else PaintingStrategy.BOOLEAN_ARROW_DOWN);

Thanks
 

mynameisdavid67

New member
If this along with the PPS buy signal are true within 3-5 bars, on either a one or five minute time frame. Buy. If price opens and closes below the 9 SMA, sell. Only to take long positions.

Code:
declare lower;
input fastLength = 12;
input slowLength = 26;
input MACDLength = 9;
input averageTypeMACD = AverageType.EXPONENTIAL;

def Diff = MACD(fastLength, slowLength, MACDLength, averageTypeMACD).Diff;

input length = 7;
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);

def twoBarPivotMACD = Diff > Diff[1] and Diff[1] > Diff[2] and Diff[2] < Diff[3] and Diff[3] < Diff[4];

def overSoldRSI = RSI <= 30;

plot TrendReversal = twoBarPivotMACD and Highest(overSoldRSI[1], 2) > 0;
 
Last edited by a moderator:

massimo

New member
Hi all, a simple question for you guys, and sorry for that but I can't find anything on the manual. I want to put an order (exit to close in the long version) just 3 days after the entry order. How can I write this???
 

dmkoch

New member
I am new to thinkscript and would appreciate any help in writing the thinkscript code for a buy/sell strategy based on ADX and DMI+; DMI- trends on a 30m chart:

Long Entry (LE)
  • Using a 30 min stock chart along with the DMI(14, Wilders) study
  • Starting with the condition that ADX <20 and below both DI- and DI+
  • When the ADX crosses above DI-, then show the LE symbol on the chart
  • When the current ADX moves lower than the previous ADX one bar ago, then show LE - Exit symbol on the chart

Short Entry (SE)
  • Using a 30 min stock chart along with the DMI(14, Wilders) study
  • Starting with the condition that ADX <20 and below both DI- and DI+
  • When the ADX crosses above DI+, then show the LE symbol on the chart
  • When the current ADX is lower than the previous ADX one bar ago, then show LE - Exit symbol on the chart
Any assistance on writing my strategy would be much appreciated.
 

VicD

Member
You mean like this or on the candlestick chart? Change arrows, I just changed colors so screwed up the colors a bit.

Code:
#aADX_DMI2 With slow moving average of ADX and Arrows

declare lower;
input MACDfastLen = 10;
input MACDslowLen = 30;
input MACDLen = 10;
input showADX_DMI = { "No", default "Yes"};
input showMACD = { "No", default "Yes"};
input invertNegMACD = { "Yes", default "No"};
input MACDHeight = 50;
input MACDWidth = 3;
input ADX_Avg = 3;
input DMI_Len = 9;
input No_Trend = 20;
input Low_Trend = 45;
input Strong_Trend = 60;


def fastAvg = EMA2(data = close, "smoothing factor" = 2 / (1 + MACDfastLen));
def slowAvg = EMA2(data = close, "smoothing factor" = 2 / (1 + MACDslowLen));
def Value = fastAvg - slowAvg;
def nextAvg = ExpAverage(data = Value, MACDLen);
def HistoBar = Value - nextAvg[1];
def HiScale = HighestAll(HistoBar);
def LoScale = AbsValue(LowestAll(HistoBar));
def BarScale = if HiScale > LoScale then HiScale else LoScale;

plot macd_plot = If (showMACD, If( invertNegMACD, If ( HistoBar < 0, ( -1 * HistoBar * MACDHeight / BarScale ), ( HistoBar * MACDHeight / BarScale )), HistoBar * MACDHeight / BarScale), Double.NaN);

macd_plot.AssignValueColor(if invertNegMACD then if HistoBar >= 0 then Color.CYAN else Color.MAGENTA else Color.CYAN);
macd_plot.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
macd_plot.SetLineWeight(MACDWidth);

def hiDiff = high - high[1];
def loDiff = low[1] - low;
def plusDM = if hiDiff > loDiff and hiDiff > 0 then hiDiff else 0;
def minusDM = if loDiff > hiDiff and loDiff > 0 then loDiff else 0;
def ATR = WildersAverage(TrueRange(high, close, low), DMI_Len);
plot "DI+" =
if showADX_DMI then 100 * WildersAverage(plusDM, DMI_Len) / ATR
else Double.NaN;
plot "DI-" =
if showADX_DMI then 100 * WildersAverage(minusDM, DMI_Len) / ATR
else Double.NaN;
def DX =
if ("DI+" + "DI-" > 0) then 100 * AbsValue("DI+" - "DI-") / ("DI+" + "DI-")
else 0;
plot ADX = if showADX_DMI then WildersAverage(DX, DMI_Len) else Double.NaN;
plot ADXAvg = if showADX_DMI then ExpAverage(ADX, ADX_Avg) else Double.NaN;
plot NoTrend = No_Trend;
plot LowTrend = Low_Trend;
plot StrngTrend = Strong_Trend;

plot ArrowUp = if "DI-" crosses above ADXAvg
               then  "DI-"
               else double.nan;
     ArrowUP.SetPaintingStrategy(PaintingStrategy.Arrow_UP);
     ArrowUP.SetLineWeight(3);
     ArrowUP.SetDefaultColor(Color.White);
plot ArrowDN = if "di+" crosses above ADXAvg
               then "di+"
               else double.nan;
     ArrowDN.SetPaintingStrategy(PaintingStrategy.Arrow_DOWN);
     ArrowDN.SetLineWeight(3);
     ArrowDN.SetDefaultColor(Color.Yellow);
Alert(ArrowUp, " ", Alert.Bar, Sound.Chimes);
Alert(ArrowDN, " ", Alert.Bar, Sound.Bell);

plot ArrowUpTrend = if "DI+" crosses above "DI-"
               then "DI-"
               else Double.NaN;
ArrowUpTrend.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
ArrowUpTrend.SetLineWeight(3);
ArrowUpTrend.SetDefaultColor(Color.green);
plot ArrowDNTrend = if  "DI+" crosses below "DI-"
               then "DI-"
               else Double.NaN;
ArrowDNTrend.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
ArrowDNTrend.SetLineWeight(3);
ArrowDNTrend.SetDefaultColor(Color.red);

"DI+".SetDefaultColor(Color.GREEN);
"DI-".SetDefaultColor(Color.RED);
ADX.SetDefaultColor(Color.WHITE);
ADXAvg.SetDefaultColor(Color.YELLOW);
 

chaba03

New member
VIP
Hi,
Below is EMA Corss over indicator. A line and arrow is displayed every time a cross over occures.
Can someone create a strategy and autotrade in such a way -
1. When the strategy starts 1 contract is taken as per the Crossover.
2. Every time the cross over Occures, two contracts are taken in opposite direction (that is also equal to - closing the old contract and opening the new contract)
3. Theoretically, the only loss will be the commission if there is no trend. If there is a trend this its always a winner.
This works in any time frame and any thick value.

Code:
#  Plots the 8 and 34 EMA 
#  Displays WHITE Candle with Directional Arrow           
#  Displays a label for TREND DIRECTION (8 VS 34)
#  Displays a label for PRICE VS 8MA      

# +---------------------------------------------------+
# |                   PLOT EMA'S                       |
# +---------------------------------------------------+

plot MA8 = ExpAverage(close, 8);
MA8.SetDefaultColor(Color.BLUE);
MA8.SetLineWeight(2);

plot MA34 = ExpAverage(close, 34);
MA34.SetDefaultColor(Color.YELLOW);
MA34.SetLineWeight(2);

plot MA8CrossUp = if MA8 crosses above MA34 then low else 0;
MA8CrossUp.SetDefaultColor(Color.WHITE);
MA8CrossUp.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
MA8CrossUp.SetLineWeight(2);
AddVerticalLine(MA8CrossUp, "8above34", Color.Green, Curve.FIRM);

plot MA8CrossDown = if MA8 crosses below MA34 then high else 0;
MA8CrossDown.SetDefaultColor(Color.WHITE);
MA8CrossDown.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
MA8CrossDown.SetLineWeight(2);
AddVerticalLine(MA8CrossDown, "8below34", Color.RED, Curve.FIRM);
AssignPriceColor(if MA8CrossUp or MA8CrossDown then Color.WHITE else Color.CURRENT);

Alert(MA8CrossUp, "8above34", Alert.BAR, Sound.Ding);
Alert(MA8CrossDown, "8below34", Alert.BAR, Sound.Ding);

# +---------------------------------------------------+
#  ADD LABEL FOR TRADE DIRECTION
# +---------------------------------------------------+

def BULLDIRECTION = if MA8 > MA34 then 1 else 0;
def BEARDIRECTION = if MA8 < MA34 then 1 else 0;

AddLabel(BULLDIRECTION, "8 ABOVE 34", Color.DARK_GREEN);
AddLabel(BEARDIRECTION, "8 BELOW 34", Color.DARK_RED);

# +---------------------------------------------------+
#      ADD LABEL FOR PRICE VS MA8 
# +---------------------------------------------------+

def BULLPRICE = if close > MA8 then 1 else 0;
def BEARPRICE = if close < MA8 then 1 else 0;

AddLabel(BULLPRICE, "PRICE: ABOVE MA8", Color.DARK_GREEN);
AddLabel(BEARPRICE, "PRICE: BELOW MA8", Color.DARK_RED);
 
Last edited by a moderator:

rogtrader

New member
I've spent a few hours to get AddOrder working.. it doesn't seem to work for me:

Code:
AddOrder(OrderType.BUY_TO_OPEN, enter_long_cond, close, TradeSize);

For the testing purposes I've just created a simple study and it doesn't do anything:

Code:
AddOrder(type = OrderType.BUY_TO_OPEN, 1, tickcolor = Color.GREEN, arrowcolor = Color.GREEN, name = "Target", price = 1);

Do I need to turn something on in Thinkorswim or TDA website? Secondly, is this a study or Strategy? This seems to be working in Strategy, but how do we automate this process using Order Rules based on Conditions?
 

cheual

New member
I'm trying to write a simple script that will buy Tuesday's open and sells Thursday's open. Then run the backtest to see what are the results. Oddly it is not work with my code below.

Am I missing something in this code? I'm using a 1M:1Day aggregation chart.

Code:
def begin = open(period = GetDayOfWeek(2));
def end = open(period = GetDayOfWeek(4));

#Backtesting
# Bullish Orders
AddOrder(OrderType.BUY_TO_OPEN, condition = begin, price = open, 1, tickcolor = Color.WHITE, arrowcolor = Color.WHITE, name = "BUY "+open);
AddOrder(OrderType.SELL_TO_CLOSE, condition = end, price = close, 1, tickcolor = Color.WHITE, arrowcolor = Color.WHITE, name = "SELL "+close);
 

ext99k

Member
Hi everyone, I'm trying to backtest my strategy using the FloatingPL and would appreciate help on adding the orders. I'd like to place a buy order once X > a number I choose, say 15...

Code:
def PC = close(period = AggregationPeriod.DAY)[1];
def PctChange = (close - PC) / PC;
Plot x = Round ((PctChange / ImpVolatility() * 100), 1);
x.SetDefaultColor(Color.WHITE);

Then I'd like to place a sell order to close the position X days later at the close... Thanks a lot for the help! Love this community!
 

adii800

Member
Wow, this looks extremely interesting! Unfortunately, I'm too uneducated in coding to help w any of that :/.

Could you explain the strategy a little bit more, specifically the indicators and the premise of a leading signal?

Thanks!
 

BenTen

Administrative
Staff
VIP
This certainly looks interesting; however, in your backtesting strategy, the buy order starts with the open of the candle. This needs to be replaced with the close of the candle for confirmation. When changing it to close, the P/L is a bit different.

80mMcMh.png
 

Similar threads

Top