AddOrder thinkScript - Backtest Buy & Sell in ThinkorSwim

@Fluideng Take a look at this example strategy here https://usethinkscript.com/threads/...rategy-based-on-ema-crossover.2664/post-26662

ThinkorSwim already include a backtesting script called MACDStrat in their platform. You can also start from there:

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

input fastLength = 12;
input slowLength = 26;
input macdLength = 9;
input averageType = AverageType.EXPONENTIAL;

def diff = reference MACD(fastLength, slowLength, macdLength, averageType).Diff;

AddOrder(OrderType.BUY_AUTO, diff crosses above 0, tickColor = GetColor(0), arrowColor = GetColor(0), name = "MACDStratLE");
AddOrder(OrderType.SELL_AUTO, diff crosses below 0, tickColor = GetColor(1), arrowColor = GetColor(1), name = "MACDStratSE");
 
Thanks, @BenTen. I will definitely learn how to code. This is all new to me. I'm still searching for a consistently wining strategy. I apologies for being inconsiderate and I truly do appreciate all the wonderful indicators you all provide here.
 
@martinstocks87 The problem is that your scan looks at an entire market whereas a strategy can only be run on a single symbol... Therefore, your idea can't be coded in Thinkscript... You could, however, possibly use parts of your scan criteria to monitor a single symbol for Buy and Sell signals and paint them onto a chart...
Hey Rad, I have the same question and intend to use my current scanner as an indicator so I can backtest and tweak the settings. How would I convert these so as to plot a bubble on my current chart at the point the scan would trigger? Ideally it would just label with the time and current price when triggered. Here are the parameters I'm using in my scan:

Any help would be greatly appreciated!

Study/Criteria all on 1 hour timeframe

Code:
PPS().Busignal is false within 3 bars (1hr)
TTM_trend upTrend 2 consecutive within last 5 bars (1hr)
williamsPercentR > -50
TTM_Wave > TTM_Wave[1]... and [1] > [2]
Randomwalkindex.highline > Lowline
MACD.value >= MACD.avg
MACD.value >= MACD.value [1]
BollingerBandwith <= to 8 within 5 bars
accumulationdistribution(length=14) >= accumulationdistribution(length=14)  [1]
accumulationdistribution(length=14) [1] >= accumulationdistribution(length=14) [2]
accumulationdistribution(length=14) >=.75

Can this be easily done?
 
We can't "get" the time when an action takes place easily in TOS... You can use AddChartBubble() in a Study/Strategy based on your criteria and simply check the timeline at the bottom of the chart though... I play very little with time functions so perhaps someone else has more experience with the time functions than I do... I'd have to research and experiment just like you would because I've never really had the need or interest... So the short answer is, no, it can't be easily done...
 
How about we just add the bubble with the last bid price? I still don't know how to write the script to use these scanner studies as an indicator though - I'm very new....
 
No worries, appreciate your help. I managed to figure out how to do it - i just copied and pasted the scan code and reformatted to if statements. Seems to be working properly and now I can tweak it on the fly as an indicator to see if I can improve results. I'll post the code below in case anyone else comes across this post with the same question. I also added the use of CamarillaPoints to make sure my entry was within 6% of the highest support level.
Code:
#support
def supportlevel = open * .94;
def Support_True = if
CamarillaPoints()."S1" is greater than or equal to supportlevel then 1 else 0;

#Accumulation
def Accumulation_True = if AccumulationDistribution("length" = 14)."RangeRatio" is greater than or equal to AccumulationDistribution("length" = 14)."RangeRatio" from 1 bars ago and AccumulationDistribution("length" = 14)."RangeRatio" from 1 bars ago is greater than or equal to AccumulationDistribution("length" = 14)."RangeRatio" from 2 bars ago then 1 else 0;
#PPS
def PPS_True = if IsNaN("value" = PPS().buysignal) is false within 3 bars then 1 else 0;

#ttm_trend
input compBars = 5;
input paintBars = yes;
input consecutiveBars = 2;
def upTrend = TTM_Trend(compBars, paintBars).TrendUp;
def downTrend = TTM_Trend(compBars, paintBars).TrendDown;
# use this to scan for x consecutive uptrend bars
#plot scan = Lowest(upTrend, consecutiveBars) > 0;
# use this to scan for x consecutive downtrend bars
#plot scan = Lowest(downTrend, consecutiveBars) > 0;

#Williams%R
def Williams_True = if WilliamsPercentR()."WR" is greater than or equal to -50 then 1 else 0;

#TTM_Wave
def TTM_Wave_True = if TTM_Wave()."Wave1" is greater than TTM_Wave()."Wave1" from 1 bars ago and TTM_Wave()."Wave1" from 1 bars ago is greater than TTM_Wave()."Wave1" from 2 bars ago and TTM_Wave()."Wave1" from 2 bars ago is greater than TTM_Wave()."Wave1" from 3 bars ago then 1 else 0;

#RandomWalk
def RandomWalk_True = if RandomWalkIndex()."HighLine" is greater than or equal to RandomWalkIndex()."LowLine" within 1 bars then 1 else 0;

#MACD
def MACD_True = if MACD()."Value" is greater than or equal to MACD()."Avg" and MACD()."Value" from 1 bars ago is greater than or equal to MACD()."Avg" from 1 bars ago then 1 else 0;

#Bollinger Bandwidth
def BollingBandwidth_True = if BollingerBandwidth()."Bandwidth" is less than 8 within 5 bars then 1 else 0;

AddChartBubble(RandomWalk_True and BollingBandwidth_True and TTM_Wave_True and Williams_True and MACD_True and PPS_True and Accumulation_True and upTrend and support_true, close, "Breakout $" + open, Color.YELLOW, yes);
 
https://tos.mx/v8QvPWS

Just put your strat in this and test

Code:
# MACD Strategy
# Mobius
# [email protected]
# V.01.07.2012

#hint: The MACD Strategy uses a MACD to generate Buy and Sell signals.
#          \n In the dafault mode it is always in the #market either Long or Short.
#          \n A Fractal Choppiness Indicator is used to #disable the Buy signal when
#              the equity is in a Choppy Zone.
#          \n Hints are at each variable click on the ? #icon.
#wizard input: n_f
#wizard text: n_f:
#hint n_f: Periods for the Fast EMA.
#wizard input: n_s
#wizard text: n_s:
#hint n_s: Periods for the Slow EMA.
#wizard input: n_n
#wizard text: n_n:
#hint n_n: Period for the Slow EMA Smoothing Function.
#wizard input: SellEndOfDay
#wizard text: SellEndOfDay:
#hint SellEndOfDay: Yes = Postion closed at the end of the day.
#           \n The signal is sent on the opening of the #next bar so make
#              sure to leave enough time for the close to #be carried out.
#wizard input: CloseTime
#wizard text: CloseTime:
#hint CloseTime: Time is Eastern Standard Time.
#wizard input: MinBeforeClose
#wizard text: MinBeforeClose:
#hint MinBeforeClose: Minutes before 1600 when the signal #is assigned.
#         \n The close will actually happen  at the open #of the following bar.
#wizard input: nC
#wizard text: nC:
#hint nC: Periods for the calculation of the Fractal Choppiness Indicator.
#wizard input: nCA
#wizard text: nCA:
#hint nCA: Periods to calculate the Average value for the Fractal Choppiness Indicator.
#wizard input: Choppy
#wizard text: Choppy:
#hint Choppy: Value indicating the beginning of the Choppy #Zone.
#               \n (Usually a value between 50 and 61.8)
#               \n Buy Signals will not be generated in #the Choppy Zone.
#               \n To disable this feature set the Value #at 100.
#wizard input: CIx
#wizard text: CIx:
#hint CIx: CIB uses the Choppiness Indicators (B)ase line #as the signal line.
#                \n CIA uses the (A)verage of the #Choppiness Indicator.

input n_f = 13;
input n_s = 21;
input n_n =  8;
input SellEndOfDay = yes;
input CloseTime = 1600;
input MinBeforeClose = 10;
input nC       = 34;
input nCA      =  8;
input Choppy   = 61.8;
input CIx = {default CIB, CIA};

def o = open;
def h = high;
def l = low;
def c = close;
def Seconds = MinBeforeClose * 60;
def secondsRemained = SecondsTillTime(CloseTime);
def F = (c * .15) +  (.85  * ExpAverage(c, n_f)[1]);
def SS = (c * .075) + (.925 * ExpAverage(c, n_s)[1]);
def MACD   = F - SS;
def MACDSL = ExpAverage(MACD, n_n);
def zero   = 0;

# Fractal Choppiness Indicator

def CIA = 100 * Log( Sum( TrueRange(h, c, l), nC))
               / ( Highest(c[1], nC) - Lowest(c[1], nC))
               / Log(nC);

def CIB = ((Log(Sum(TrueRange(h, c, l), nC) /
              (Highest(if h >= c[1]
                       then h
                       else c[1], nC) - Lowest( if l <= c[1]
                                                then l
                                                else c[1], nC))) / Log(10)) / (Log(nC) / Log(10))) * 100;
def CI = if CIx == CIx.CIB
            then CIB
            else CIA;
def CIavg = Average(CI, nCA);
def ex    = if CIavg > Choppy
               then 1
               else 0;

# Chart Management
AssignPriceColor(if ex == 1
                    then Color.YELLOW
                    else if MACD > 0 and
                            MACD > MACD[1] and
                            MACD[1] > MACD[2]
                         then Color.GREEN
                         else if MACD < 0 and
                                 MACD > MACDSL
                         then Color.GRAY
                         else if MACD crosses above 0
                         then Color.WHITE
                         else if MACD crosses below 0
                         then Color.BLUE
                         else Color.RED);

# Order Management

def buy = ex != 1 and
               ( MACD > MACDSL and
                 MACD > 0 or
                 MACD crosses Lowest(MACD, n_s));
def sell = if SellEndOfDay == yes
              then
                ( secondsRemained >= 0 and
                  secondsRemained <= Seconds
                ) or
                 ( MACD < MACDSL and
                   MACDSL < MACDSL[1] and
                   MACDSL[1] > MACDSL[2]
                 ) or
                   MACD crosses below 0
                   or
                   MACD crosses Highest(MACD, n_s)
             else
                 ( MACD < MACDSL and
                   MACDSL < MACDSL[1] and
                   MACDSL[1] > MACDSL[2]) or
                   MACD crosses below 0 or
                   MACD crosses Highest(MACD, n_s)
              ;

AddOrder(OrderType.BUY_AUTO, condition = buy,
                             price = open[-1],
                             tickcolor = Color. GREEN,
                             arrowcolor = Color.GREEN,
                             name = "BUY");

AddOrder(OrderType.SELL_AUTO, condition = sell,
                              price = open[-1],
                              tickcolor = Color.RED,
                              arrowcolor = Color.RED,
                              name = "SELL");

# End Code

Code:
############################
# FPL Extended
# Extended Floating P&L study.
# Author: Eddielee394
# Version: 1.2
# inspired by FPL Dashboard script developed by Mobius
#
############################

#Hint: An extended floating P&L study to be used alongside TOS strategies for measuring hypothetical strategy performance.\nThis is a work in progress.  And may contain some bugs or other programming issues.

############################
# Instructions
# - Due to limitations with the thinkscript public api, this specific script must be added to a "strategy" study.
#   Generally best practice is to append this script to the end of your custom strategy (ensuring it runs AFTER the
#   `AddOrder()` function is called from the strategy).  A better method would be to use as a lower study but unless
#    a workaround is implemented to handle the `Entry()` function in a lower study, it can only be applied to upper strategies.
#
# - the script uses the `HidePrice()` function which will hide the actual price candles within the upper study,
#   only displaying the FPL histogram.
#
############################


############################
#    Metrics              
#  - Active Trade return %
#  - Entry Count          
#  - Winning Entry Count  
#  - Win rate            
#  - Avg return          
#  - avg win              
#  - avg loss            
#  - peak to valley dd    
#  - largest equity dd    
#  - P&L low              
#  - P&L high            
#  - Highest return    
#  - Lowest return      
############################

############################
#     Todo:              
# - Sharpe Ratio    
# - Sortino Ratio    
# - Calmar Ratio    
# - Avg trade          
#   duration            
# -Buy/hold comparison    
############################


#Globals
def nan = Double.NaN;
def bn = if !IsNaN(close) and !IsNaN(close[1]) and !IsNaN(close[-1]) then BarNumber() else bn[1];

#Inputs
input fplBegin = 0000;
#hint fplBegin: start time: the time in which then dailyHighLow profit should consider the day start.  Recommended value is 0000.

input fplTargetWinLoss = .50;
#hint fplTargetWinLoss: sets the target winlossRatio (in percent) which determines display colors of the W/L label.

input fplTargetWinRate = 1;
#hint fplTargetWinRate: sets the target winRate (float) which determines display colors of the WinRate label;

input fplHidePrice = no;
#hint fplHidePrice: hide's the underlying price graph. \nDefault is no.

input fplHideFPL = yes;
#hint fplHideFPL: hide's the underlying P&L graph.\nDefault is yes.

input fplShowEntryBubbles = no;
#hint fplShowEntryBubbles: display bubbles on the FPL showing the entry and exit P&L values

input fplEnableDebugging = no;
#hint fplEnableDebugging: displays various debugging labels and chart bubbles. \nIt's recommended to hide the price chart & set the fpl hide fpl setting to yes, when enabling.

#temp input var references
def begin = fplBegin;
def targetWinLoss = fplTargetWinLoss;
def targetWinRate = fplTargetWinRate;
def hidePrice = fplHidePrice;
def hideFPL = fplHideFPL;
def showEntryBubbles = fplShowEntryBubbles;
def enableDebugging = fplEnableDebugging;

#hide chart candles
HidePricePlot(hidePrice);

#Plot default Floating P&L
plot FPL = FPL();
FPL.SetPaintingStrategy(PaintingStrategy.SQUARED_HISTOGRAM);
FPL.DefineColor("Positive and Up", Color.GREEN);
FPL.DefineColor("Positive and Down", Color.DARK_GREEN);
FPL.DefineColor("Negative and Down", Color.RED);
FPL.DefineColor("Negative and Up", Color.DARK_RED);
FPL.AssignValueColor(if FPL >= 0
                            then if FPL > FPL[1]
                            then FPL.Color("Positive and Up")
                            else FPL.Color("Positive and Down")
                            else if FPL < FPL[1]
                            then FPL.Color("Negative and Down")
                            else FPL.Color("Negative and Up"));
FPL.SetHiding(hideFPL);

plot ZeroLine = if IsNaN(close)
                then nan
                else 0;
ZeroLine.SetDefaultColor(Color.GRAY);
ZeroLine.SetHiding(hideFPL);

#Global Scripts
script calculateDrawdown {
    input plLow = 1;
    input plHigh = 1;

    def _drawdown = if plHigh == 0
                   then 0 #handles the divide by zero error
                   else (plLow - plHigh) / plHigh;
    plot calculateDrawdown = _drawdown;
}

script incrementValue {
    input condition = yes;
    input increment =  1;
    input startingValue = 0;

    def _value = CompoundValue(1,
                 if condition
                 then _value[1] + increment
                 else _value[1], startingValue);

    plot incrementValue = _value;
}
;

script getDurationInMins {
    input gdimBarCount = 1;

    #get the aggregation period (MS per bar)
    def aggPeriod = GetAggregationPeriod();

    #multiply length of bars by aggPeriod to determine total milliseconds then convert to minutes
    def _getDurationInMins = Floor((gdimBarCount * aggPeriod) / 60000);
    plot getDurationInMins = _getDurationInMins;
}

script formatDuration {
    input fdBarCount = 1;
    def _fdDuration = getDurationInMins(fdBarCount);
    def _formatDuration = if _fdDuration >= 60 and _fdDuration < 1440 #hours but not days
                         then 1
                         else if _fdDuration >= 1440 #days
                         then 2
                         else 0;

    plot formatDuration = _formatDuration;
}

script calculateDuration {
    input cdBarCount = 1;
    def _cdDurationFormat = formatDuration(cdBarCount);
    def _cdDuration = getDurationInMins(cdBarCount);
   
    #if minutes > hour convert to hour, else if minutes > day, then convert to days
    def _calculateDuration = if _cdDurationFormat == 1
                             then _cdDuration / 60 #convert to hours if greater than 60min but less than a day (1440)
                             else if  _cdDurationFormat == 2
                             then Ceil(_cdDuration / 1440) #convert to days if greater than 1440mins
                             else _cdDuration; #fallback to minutes

    plot calculateDuration = _calculateDuration;
}

# Entry Calculations.  Note: Only parses on a Strategy Chart
def entry = EntryPrice();

def entryPrice = if !IsNaN(entry)
                 then entry
                 else entryPrice[1];

def hasEntry = !IsNaN(entry);

def isNewEntry = entryPrice != entryPrice[1];

#is active trade
def Active = if SecondsTillTime(begin) == 0 and
                SecondsFromTime(begin) == 0
             then 1
             else 0;

def highFPL = HighestAll(FPL);
def lowFPL = LowestAll(FPL);

def fplreturn = (FPL - FPL[1]) / FPL[1];
def cumsum = Sum(fplreturn);

def highBarNumber = CompoundValue(1, if FPL == highFPL
                                     then bn
                                     else highBarNumber[1], 0);

def lowBarNumber = CompoundValue(1, if FPL == lowFPL
                                    then bn
                                    else lowBarNumber[1], 0);


#Win/Loss ratios
def entryBarsTemp = if hasEntry
                    then bn
                    else nan;

def entryBarNum = if hasEntry and isNewEntry
                  then bn
                  else entryBarNum[1];

def isEntryBar = entryBarNum != entryBarNum[1];

def entryBarPL = if isEntryBar
                 then FPL
                 else entryBarPL[1];

def exitBarsTemp = if !hasEntry
                   and bn > entryBarsTemp[1]
                   then bn
                   else nan;

def exitBarNum = if !hasEntry and !IsNaN(exitBarsTemp[1])
                 then bn
                 else exitBarNum[1];

def isExitBar = exitBarNum != exitBarNum[1];

def exitBarPL = if isExitBar
                then FPL
                else exitBarPL[1];

def entryReturn = if isExitBar then exitBarPL - exitBarPL[1] else entryReturn[1];
def isWin = if isExitBar and entryReturn >= 0 then 1 else 0;
def isLoss = if isExitBar and entryReturn < 0 then 1 else 0;
def entryReturnWin = if isWin then entryReturn else entryReturnWin[1];
def entryReturnLoss = if isLoss then entryReturn else entryReturnLoss[1];
def entryFPLWins = if isWin then entryReturn else 0;
def entryFPLLosses = if isLoss then entryReturn else 0;
def entryFPLAll = if isLoss or isWin then entryReturn else 0;


#Counts
def entryCount = incrementValue(entryFPLAll);
def winCount = incrementValue(isWin);
def lossCount = incrementValue(isLoss);

def highestReturn = if entryReturnWin[1] > highestReturn[1]
                    then entryReturnWin[1]
                    else highestReturn[1];

def lowestReturn = if entryReturnLoss[1] < lowestReturn[1]
                   then entryReturnLoss[1]
                   else lowestReturn[1];


def winRate = winCount / lossCount;
def winLossRatio = winCount / entryCount;
def avgReturn = TotalSum(entryFPLAll) / entryCount;
def avgWin = TotalSum(entryFPLWins) / winCount;
def avgLoss = TotalSum(entryFPLLosses) / lossCount;

#Drawdown
def lowestLowBarNumber = HighestAll(if FPL == lowFPL then bn else 0);
def highestHighBarNumber = HighestAll(if FPL == highFPL and FPL != FPL[1] then bn else 0);
def hasPrevLow = lowestLowBarNumber < highestHighBarNumber;

def isPeak = FPL > Highest(FPL[1], 12) and FPL > Highest(FPL[-12], 12);
def isTrough = FPL < Lowest(FPL[1], 12) and FPL < Lowest(FPL[-12], 12);
def _peak = if isPeak then FPL else nan;
def _trough = if isTrough then FPL else nan;
def peak = if !IsNaN(_peak) then FPL else peak[1];
def trough = if !IsNaN(_trough) then FPL else trough[1];
def peakBN = if isPeak then bn else peakBN[1];
def troughBN = if isTrough then bn else troughBN[1];

def ptvDrawdown = if !hasPrevLow then calculateDrawdown(lowFPL, highFPL) else ptvDrawdown[1];
def equityDrawdown = if isTrough and trough < peak then trough - peak else equityDrawdown[1];
def equityDrawdownPercent = if isTrough and trough < peak then calculateDrawdown(trough, peak) else equityDrawdownPercent[1];
def largestEquityDrawdown = LowestAll(equityDrawdown);
def largestEquityDrawdownPercent = LowestAll(equityDrawdownPercent);

def drawdown = if hasPrevLow
               then largestEquityDrawdownPercent
               else ptvDrawdown;

# Drawdown Durations
def equityDrawdownLength = if bn >= peakBN and bn <= troughBN
                           then troughBN - peakBN
                           else equityDrawdownLength[1];

def ptvDrawdownLength = if bn >= highestHighBarNumber and bn <= lowestLowBarNumber
                        then lowestLowBarNumber - highestHighBarNumber
                        else ptvDrawdownLength[1];

def equityDrawdownDuration = calculateDuration(HighestAll(equityDrawdownLength));
def equityDrawdownDurationFormat = formatDuration(HighestAll(equityDrawdownLength));
def ptvDrawdownDuration = calculateDuration(ptvDrawdownLength);

def ptvDrawdownDurationFormat = formatDuration(ptvDrawdownLength);

#Daily profit
def Midnight = if Active then FPL else Midnight[1];
def DaysProfit = FPL - Midnight;

#Plots

AddChartBubble(!hideFPL and showEntryBubbles and isEntryBar, FPL, "Entry: " + entryBarPL + " | " + bn, Color.WHITE);
AddChartBubble(!hideFPL and showEntryBubbles and isExitBar, FPL, "Exit: " + exitBarPL,
               color = if isWin
                       then Color.LIGHT_GREEN
                       else if isLoss
                       then Color.DARK_RED
                       else Color.GRAY,
               up = no
              );

#Labels

AddLabel(yes,
         text = "LastEntry: " + AsPrice(entryPrice)
         );

AddLabel(hasEntry,
         text = "Current Trade % Return:  " + AsPercent(cumsum),
         color = if cumsum > 0
         then Color.GREEN
         else Color.RED
        );

AddLabel(yes,
         text = "Total Trades: " + entryCount,
         color = Color.WHITE
         );

AddLabel(yes,
         text = "WinCount: " + winCount +
                " | LossCount: " + lossCount +
                " | WinRate: " + winRate,
         color = if winRate >= targetWinRate
                 then Color.GREEN
                 else Color.RED
         );

AddLabel(yes,
         text = "W/L: " + AsPercent(winLossRatio),
         color = if winLossRatio > targetWinLoss
                 then Color.GREEN
                 else Color.RED
         );

AddLabel(yes,
        text = "HighestReturn: " +  AsDollars(highestReturn),
        color = if highestReturn > 0
                then Color.GREEN
                else Color.RED
        );

AddLabel(yes,
        text = "LowestReturn: " +  AsDollars(lowestReturn),
        color = if lowestReturn > 0
                then Color.GREEN
                else Color.RED
        );

AddLabel(yes,
         text = "AvgReturn: " + AsDollars(avgReturn) +
                " | AvgWin: " + AsDollars(avgWin) +
                " | AvgLoss: " + AsDollars(avgLoss),
         color = if avgReturn >= 0
                 then Color.LIGHT_GREEN
                 else Color.RED
         );

AddLabel(yes,
        text = "PeakToValley DD: " +  AsPercent(drawdown) +
               " | Duration: " + ptvDrawdownDuration +
                if ptvDrawdownDurationFormat == 1
                then " hours"
                else if ptvDrawdownDurationFormat == 2
                then " days"
                else " mins" ,
        color = if drawdown > 0
                then Color.GREEN
                else Color.RED
        );


AddLabel(largestEquityDrawdown < 0,
        text = "Largest Equity DD: " +  AsDollars(largestEquityDrawdown) +
               " | Duration: " + equityDrawdownDuration +
                if equityDrawdownDurationFormat == 1
                then " hours"
                else if equityDrawdownDurationFormat == 2
                then " days"
                else " mins",
        color = if largestEquityDrawdown > 0
                then Color.GREEN
                else Color.RED
        );

AddLabel(yes,
         text = "P&L High" +
                (if enableDebugging
                then " at bar " + highBarNumber
                else "") +
                ":  " + AsDollars(highFPL),
        color = Color.GREEN
       );

AddLabel(yes,
         text = "P&L Low" +
                (if enableDebugging
                then " at bar " + lowBarNumber
                else "") +
                ":  " + AsDollars(lowFPL),
        color = Color.RED
       );

AddLabel(yes,
         text = "Days Profit: $" + DaysProfit,
         color = if DaysProfit > 0
                 then Color.GREEN
                 else Color.RED
        );

AddLabel(yes,
         text = "Total Profit: " + AsDollars(FPL),
         color = if FPL > 0
                 then Color.GREEN
                 else Color.RED
        );

#debugging

#peaks & troughs
AddChartBubble(enableDebugging and isPeak, FPL,
               text = "FPL: " + FPL
                      + " | Peak: " + peak
                      + " | Trough: " + trough[-1]
                      + " | Drawdown: " + AsPercent(calculateDrawdown(trough, peak))
                      + " | PeakBN: " + peakBN
                      + " | BarNumber: " + bn,
               color = Color.LIME
              );

AddChartBubble(enableDebugging and isTrough, FPL,
               text = "FPL: " + FPL
                      + " | Peak: " + peak
                      + " | Trough: " + trough
                      + " | Drawdown: " + AsPercent(calculateDrawdown(trough, peak))
                      + " | TroughBN: " + troughBN
                      + " | BarNumber: " + bn,
              color = Color.LIGHT_RED,
              up = no
             );

AddVerticalLine(enableDebugging and isEntryBar,
                text = "EntryBarNum: " + entryBarNum
                       + " | ExitBarNum: " + exitBarNum[-1]
                       + " | BarNumber: " + bn,
                color = Color.WHITE
);

AddVerticalLine(enableDebugging and isExitBar,
                text =  "EntryBarNum: " + entryBarNum[1]
                        + " | ExitbarNum: " + exitBarNum
                        + " | BarNumber: " + bn
                        + " | EntryReturn: " + entryReturn,
                color = if isWin
                        then Color.LIGHT_GREEN
                        else if isLoss
                        then Color.LIGHT_RED
                        else Color.LIGHT_GREEN
);
 
Last edited by a moderator:
Hi @BenTen and experts, not sure if this has been discussed before or if I'm doing something wrong. I get big gaps between what the strategy P/L report shows vs actual price. This is a common problem across any strategy I see or use.
I tried to use many variations of price entry (Open, Close, High, Low, (Open+close/2), (Open+High+close+low/4) etc.,

AddOrder(OrderType.Buy_auto, UpSignal , high, tradesize, name = "Buy");
AddOrder(OrderType.Sell_auto, DownSignal, low, tradesize,name = "Sell");

lm43MpH.jpg


I know that we cannot use the backtesting entries in real trades but even to check the correct entry price limits me to try any strategy.
Hope I was clear with my problem and any help/guidance will be much appreciated.

Thanks
Stock
 
@Stockbat There's some bugs and oddities in the AddOrder functionality. The details are a bit fuzzy now as it's been a few months since I was playing with strategies. I think it's something like it assumes everything is a market order at the beginning of the following candle. Like if you want to buy the break of the current candle's high instead it buys the next candle's open. That may not be exactly right but it's something odd like that.

I was able to work around the weirdness by using a negative index to look ahead and cause it to place the orders on the correct candles. And you can set the price to a specific value. For instance:
Ruby:
AddOrder(OrderType.BUY_TO_OPEN, isTrigger[-1], open[-1], RoundDown(risk / (high - low + .02), 0), GetColor(8), GetColor(8), "LE");

Additional weirdness is you can't buy and sell on the same candle but you can fake it by placing the order on the next candle at the correct price even if that price doesn't exist on that candle (it'll look like the trigger price floating below your candle in your screen shot).
Also, you can open a position with a calculated number of shares but no matter how many shares you try to exit it closes the whole position. I didn't see a way to test partial exits.
End of day exits if you're not using 1m chart were also funky to do because of the look ahead thing. You have to exit a whole candle before the end of day. Or maybe it was two whole candles. There was something weirder than expected about it.

That's all I remember at the moment. I hope it helps.
 
Last edited by a moderator:
Thanks @Slippage, I will try your suggestion. isTrigger is the condition, entryprice is my desired price (open, high, close etc)., whats risk in your example?, a value which you derive based on your strategy logic?
 
@Stockbat Risk in that case is just how much money I'm willing to lose per trade. It calculates how many shares you can trade to risk $100 given the entry and stop loss being above and below the entry candle. For back testing I usually use $100 since it's a nice round number. I prefer a fixed $ risk rather than a fixed share size.

Ruby:
input risk = 100;

You can replace that chunk of code in the AddOrder call with a fixed number of shares if you don't want to deal with the stop loss yet or use some other stop loss exit strategy.
 
Last edited:
Someone please clarify just what the "AddOrder()" command actually does. Is this just to display an icon on the chart as to when to buy or sell or does it execute a realtime trade? I've been searching for a way to hide my orders from the brokers and market makers and I've come across terms like "Automated Trading" and "Anonymous Trading". Is this what the "AddOrder()" command does for ThinkOrSwim?
 
@Picard for actual automated trading look into TradeStation and/or NinjaTrader. There's a YouTuber running automated strategies on both platforms you can check out and maybe learn something. https://www.youtube.com/user/capstonets I added him to my subscriptions but I haven't taken the time to dig into yet until I find a strategy I think is worth automating and is possible to be automated, then trade it manually for long enough to trust it.

The only way for orders to not be seen is to not place orders that don't execute immediately. Assuming you're using market orders and no stops or limits at least the automation should have faster reaction time than you.
 
There's a video on YouTube that discusses the use of triggers from indicator codes. Is this a way of doing automated trades on TOS?Possibly the market makers might not see this on their screens? This is the first that I've seen this type of trading order.
 
There's a video on YouTube that discusses the use of triggers from indicator codes. Is this a way of doing automated trades on TOS?Possibly the market makers might not see this on their screens? This is the first that I've seen this type of trading order.

As previously stated, TOS does not support automated trading... The only thing you can do in TOS is use Conditional Orders which need to be restarted after every iteration... You would enter a Conditional Buy Order and a Conditional Sell Order using a Trigger Order Type...
 
Last edited by a moderator:
@guga If you don't want after-hours data to be included in your strategy report, then you can turn it off by going to your chart settings > Equities > uncheck "Show Extended Hours Trading Session"
 
Hey Ben, I went back to check my chart as I was pretty sure it didn't have extended hours on. So it seems that's not the issue really. Any other idea? Thanks

MuXpjbI.png
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
437 Online
Create Post

Similar threads

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.
Back
Top