AddOrder thinkScript - Backtest Buy & Sell in ThinkorSwim

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?

If ext hours is already off and it's still executing trades at times you don't want you can add your own time filters. Here's code I used to test a strategy only during the regular session and also have control to test various smaller periods within the session. In this case it's only trading in the first two hours and not opening trades on the first or last candle of the day. You can change however you want and then add isValidTime in your conditions that control AddOrder.

Ruby:
input timeToStart = 0930;
input timeToStop = 1130;
def isBeforeStartTime = SecondsTillTime(timeToStart) >= 1;
def isAfterStopTime = SecondsFromTime(timeToStop) >= 0;
def period = GetAggregationPeriod();
def isTooEarly = GetTime() < RegularTradingStart(GetYYYYMMDD()) + period;
def isTooLate = GetTime() > RegularTradingEnd(GetYYYYMMDD()) - period;
def isValidTime = !(isTooEarly or isTooLate or isBeforeStartTime or isAfterStopTime);

And if you want to exit trades at end of day
Ruby:
input barsFromEnd = 1;
def EOD = RegularTradingEnd(GetYYYYMMDD()) - GetTime() <= GetAggregationPeriod() * barsFromEnd - 1;
AddOrder(OrderType.SELL_TO_CLOSE, EOD[-1], open[-1], 0, Color.ORANGE, Color.ORANGE, "EOD LX");
AddOrder(OrderType.BUY_TO_CLOSE, EOD[-1], open[-1], 0, Color.ORANGE, Color.ORANGE, "EOD SX");
 
Last edited by a moderator:
@guga In addition to the advice @BenTen provided, you may also need to un-check the Start aggregations at market open checkbox in that same panel section as well, if you haven't already...
 
I've play with adding arrows several times, as I stated, and they just aren't reliable enough to trust having them on my charts...

As to you comments regarding backtesting, they truly aren't accurate enough to base any trading off of them... Strategies represent ideal situations only and often repaint away bad trades only to keep good trades... I don't rely on them at all and, instead, usually manually calculate my backtesting trades, knowing that there is a percentage of error along the way... The use of stop-loss in Strategies is an absolute joke and I can calculate them more accurately using my manual methods... Strategies merely prove that your trade logic "could" work...
I don't find that to be the case at all. Perhaps it depends on what, if any, indicators the strategy is built on. I have one strategy (two if you count the short version of the same strategy) that I've live traded with for several months. It's rock solid. It's based purely on price action, though. No indicators.

Originally, I had it on my charts to watch for bugs in the strategy. After a short while there was nothing left to fix and I kept it on my charts as a visual cue for trading as well as to easily see how my strategy worked on stocks I didn't trade that day or after I stopped trading that day or to keep an eye on trades I skipped because I didn't like the setup. Once I trusted it I did a ton of back-testing with varying timeframes and other parameters to find out what worked best.

Yes, back test scripts assume it's a perfect world where there's no slippage, limit orders never get skipped, etc. Humans make the same assumptions when manually back-testing. But, so what? You can still compare perfect world results with one set of settings against perfect world results with a different set of settings and see which is more profitable.
 
Last edited:
@Slippage Perhaps you misunderstood my phrase of "Strategy", meaning the ones in TOS or coded into custom Strategies, not overall trading strategies... My trading strategies, or trading systems if you will, are far more reliable that some script painting Buy ad Sell signals... That type of logic is what causes beginning traders to lose money... It pays to be able to read into the trade rather than to think it possible to code enough logic to cover every aspect of live trading via Buy and Sell signals... No offense intended or taken... I merely post information to help traders not lose money, and hopefully profit on their trades...
I'm talking about a custom scripted strategy that I wrote in ThinkScript and applied to my charts. It works fine. If a strategy is objective enough to be expressed in code there's no problem. Not all strategies are and that doesn't make them inferior in any way. Just more difficult to back test. And there are certainly days when I ignore signals from the strategy due to factors such as SPY moving swiftly in the opposite direction.

I do agree with you, though, that new traders relying on coded strategy signals or indicator arrows are going to lose money. I think that's just part of the process, though, unless you can find a winning strategy from a friend, mentor, paid course, luck, almost never youtube -- I spent hundreds of hours gaining almost entirely useless information from youtube when I started.
 
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,
                             tickcolor = Color. GREEN,
                             arrowcolor = Color.GREEN,
                             name = "BUY");

AddOrder(OrderType.SELL_AUTO, condition = sell,
                              price = open,
                              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
);
Thanks Mobius! It would totally cool to be able to see how this strategy stacks up against other stocks, on a "%winning trades" and/or "%Loss Trades" basis for the period in use at the time. It appears that there is code intended to supply that, but it does not appear for me.
 
Thanks Mobius! It would totally cool to be able to see how this strategy stacks up against other stocks, on a "%winning trades" and/or "%Loss Trades" basis for the period in use at the time. It appears that there is code intended to supply that, but it does not appear for me.
This chart that I posted has a MACD Strategy installed: https://tos.mx/v8QvPWS
It declares the P/L in the labels.
 
Hello -

I want to be able to replicate a strategy in a scan such that my scan results would only trigger if I were not already in that trade.

For example, if my strategy fired a long entry on March 1 and I entered a trade and remained in it, the criteria that triggered the entry could also occur again on March 5. Since I am already in the trade the strategy would not show another entry point but the scan would as it does not see the AddOrder.

I want to add code into my scan to see if my last signal was an entry and if true then not alert in the scan results. I was thinking that I could add a flag that would track my last signal, entry or exit, and incorporate that into my scan. I am not having luck constructing this, any thoughts?

Regards
 
Hello -

I want to be able to replicate a strategy in a scan such that my scan results would only trigger if I were not already in that trade.

For example, if my strategy fired a long entry on March 1 and I entered a trade and remained in it, the criteria that triggered the entry could also occur again on March 5. Since I am already in the trade the strategy would not show another entry point but the scan would as it does not see the AddOrder.

I want to add code into my scan to see if my last signal was an entry and if true then not alert in the scan results. I was thinking that I could add a flag that would track my last signal, entry or exit, and incorporate that into my scan. I am not having luck constructing this, any thoughts?

Regards

As you probably know, what you are describing is a Strategy and, as such, you can set a Strategy to not allow more than one entry... Now, if you are looking to not have the Strategy fire if you are still in an actual real trade then you could use any of several Thinkscript functions... Some work for both real trades as well as backtesting using AddOrder()... EntryPrice() is one such function, which can be used in both Studies and Strategies... In a Study it "should" only work for real trades... GetAveragePrice(), GetOpenPL(), and PositionOpenPL() are a few others... You can learn more about those and others in the Thinkscript Learning Center... Good luck... (y)
 
Hello,

I am playing with a strategy and trying to figure out how to reverse my position from long to short, or short to long, at the same moment on the start on a new candle given a condition seen in the previous candle.

The goal is to look at market conditions, go long or short on the first order, and then reverse all orders thereafter, rather than close the order, and wait to open a new order on the next candle.

Below is a generic excerpt of my current code.

The problem with this code is that it closes my position in one candle, and then opens my new position in the next candle. The floating P&L does not calculate properly then because it seems to be based on the opening price of a candle. It misses what has happened to the price from the open of the candle with the closing position to the open of the candle with the new starting position. I have found a way to post process the data after exporting the csv file into Excel, but it would be nice to have thinkorswim code that does it without post processing.

Hopefully “Order Reversal” is something easy to do that I’ve overlooked. I’ve done some digging, but am surprised to not find any code for it, especially when TOS has a button for it in Active Trader.

Thanks,
Tim
——
AddOrder(OrderType.BUY_TO_OPEN, Condition1 < Condition2, tickcolor = Color.GREEN, arrowcolor = Color.GREEN, name = "TMB_LO");

AddOrder(OrderType.SELL_TO_CLOSE, Condition1 > Condition2, tickcolor = Color.GREEN, arrowcolor = Color.RED, name = "TMB_LC");

AddOrder(OrderType.SELL_TO_OPEN, Condition1 > Condition2, tickcolor = Color.GREEN, arrowcolor = Color.GREEN, name = "TMB_SO");

AddOrder(OrderType.BUY_TO_CLOSE, Condition1 < Condition2, tickcolor = Color.GREEN, arrowcolor = Color.RED, name = "TMB_SC");
——-
 
@TMB70 While your concept sounds ingenious, in reality such a concept would most likely prove unprofitable or, at the very least, less profitable than waiting for confirmed trend reversal or continuation, with confirmed momentum... Sure, you could code a Strategy to do trades as per your conditions but in real trading there are far more factors involved...
 
Last edited by a moderator:
@TMB70 While your concept sounds ingenious, in reality such a concept would most likely prove unprofitable or, at the very least, less profitable than waiting for confirmed trend reversal or continuation, with confirmed momentum... Sure, you could code a Strategy to do trades as per your conditions but in real trading there are far more factors involved... If we could trade the way our Strategies can be coded to show we'd all be rich...

I'm not trying to be a nay-sayer, I'm just being a realist... Remember, even with Conditional Orders your trades would never play out as ideal as a backtested Strategy can portray... What you really need is a set of indicators that provide adequate information and then use your noggin to make actual trade decisions... There is no "Holy Grail" that is simply going to give you consistently winning Buy and Sell indicators of any kind, whether Alerts, Chart Labels, Chart Bubbles, or Watchlist Columns... And playing the luck of the odds is just gambling, not trading...

I'm currently mentoring a trader who has been doing nothing but gambling for years and now wants to be a more profitable trader... Simply relying on "hunches", "advice", and inadequate indicators just won't prove overly profitable, and perhaps not profitable at all... He's finally seeing the light and I'm thrilled every time he has an "Aha!" moment when things finally click...

Again, I'm not shooting down your idea, I'm merely conveying some reality based on years of experience and providing some food for thought...
Thanks for the reply and I appreciate the advice. I am not sure that the idea is ingenious, but I would at least like the ability to test the strategy. Trust me that every time I think I’ve found a winning strategy, I spend a little time with it just watching and observing how it works, or playing with small share size, and sometimes find out that the signal I received to buy or sell disappears a candle or two later.
At any rate, do you know how to code an order reversal?
Thanks
 
@TMB70 If you use AddOrder Buy_Auto and Sell_Auto it should do what you want automagically... It'll pivot from Long to Short...
Thanks again for the tip on the code. I have implemented it. It helped me to find an error in what I had previously coded (without the true reversal), as well as the post processing of the previous csv file. As expected, the results were not as successful as I had hoped, but at least I was able to see it more clearly in TOS. Thanks again.
 
This could be very basic question, but wanted to make sure I ask ...
When we add AddOrder(.....) function for a given condition, will ToS really generate an order and if so where I can see it...
I could see only the relative condition output just being displayed on the chart... or is it just mean for that only ?
Any help appreciated...
 
This could be very basic question, but wanted to make sure I ask ...
When we add AddOrder(.....) function for a given condition, will ToS really generate an order and if so where I can see it...
I could see only the relative condition output just being displayed on the chart... or is it just mean for that only ?
Any help appreciated...

The AddOrder() function is intended for Strategy backtesting only and, as such, only paints the theoretical trade entries and exits on your charts based on your criteria... TOS does not support auto-trading aside from one-shot conditional orders...
 
@rad14733 Thanks so much ... have been struggling with this lack of understanding :)
Also one more qq... Reg the Entryprice() function, is this also limited to usage within AddOrder() function (that naturally restricts Entryprice function to back testing) or can it be used in any other place of the script. As such I am building a new sell price condition based on EntryPrice and never getting any output. TIA for your insights...
 
Also one more qq... Reg the Entryprice() function, is this also limited to usage within AddOrder() function (that naturally restricts Entryprice function to back testing) or can it be used in any other place of the script. As such I am building a new sell price condition based on EntryPrice and never getting any output. TIA for your insights...

EntryPrice() also works with live trades, as do GetAveragePrice(), GetQuantity(), and a few others...
 
Last edited by a moderator:
EntryPrice() also works with live trades, as do GetAveragePrice(), GetQuantity(), and a few others...
I don’t see any portfolio functions in the conditional orders section. EntryPrice() is there (but it’s not in the portfolio section).
Also, I checked to confirm I do have “Advanced Trading” turned on from the Ameritrade website, but no portfolio functions available at the conditional order screen. I messaged TD chat support and was told portfolio functions are not available in conditional orders. Did something change?
 
Last edited by a moderator:

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
285 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