3 SuperTrend + Support and Resistance Level Strategy for ThinkorSwim

C

chaba03

New member
VIP
Hi,
First of all thanks a TONNNN for this lovely script.
I loaded script against the futures market. This showed very promising numbers.

I am new to TOS. I was using Tradestatio in the past and switched to TOS as I felt this TOS is more userfriendly.
Few questions.. appricaite if you can help..
Indicator shows like "Buy 100(200)" "Sell 0(0)" and "Sell 100(200)" "Buy 0(0)" What does this mean ?
if it is 100 stocks.. Is it possible to set number of contracts to trade.
Also the $values caliculated is based on Futures ticks or only Stocks value ?


Thanks
 
YungTraderFromMontana

YungTraderFromMontana

Well-known member
For today, Thursday, April 23, the strategy was profitable on 27% of the S&P 500 stocks (54% of the stocks were up in price on the day). Again, those with the largest percentage difference between their intraday highs and lows performed better: 1-100 (highest variance) = 50% profitable, 101-200 = 36%, 201-300 = 21%, 301-400 = 16%, 401-500 (lowest beta) = 13%. Today I paper traded six stocks that were among the most variable in the first hour of the session. Half were profitable. Unfortunately the losses outweighed the gains. I am finding it very difficult to rely on this as a profitable strategy. As some have mentioned in this thread, some tinkering of the settings may be needed to find more success. Even with fictious money the wins just aren't adding up. Any suggestions?
How are you getting all of that cool data about percent of s & p stocks as well highest variance?
 
H

heramone

New member
VIP
This script does not work on TOS at all? Any advise?
 
Midtown Mo

Midtown Mo

New member
How are you getting all of that cool data about percent of s & p stocks as well highest variance?
This SuperTrend strategy appears to have higher profit correlation with stocks that have wider trading ranges during the day and on days when the volume is higher than average. To prove this I download each day the high and low for each of the S&P 500 stocks from http://finance.jasonstrimpel.com/bulk-stock-download/. Next for each stock divide the high by the low and sort on this column. This gives you the stocks with the highest intraday variance. Next I run a single-day chart for each of the 500 stocks in the S&P 500 and record that day's total profit from the SuperTrend strategy. I have backtested this for each trading day since January 27. I wanted to see if the strategy was profitable before the virus sell off, during it, and since we came off the lows. Happy to report it was profitable in all three time periods, but the highest profit was during the crash as volatility and volume increased. It's not perfect but when analyzing trades for a group of 10 stocks that are in the group to be that day's most volatile, over the past 63 trading days, the strategy was profitable on 76% of the days and the average winner was twice as high as the average loser. This is based on my analysis of more than 11,700 trades across a variety of S&P 500 stocks. These profits were achieved even though only 42% of the trades were profitable. As you know, there can be many false signals but the fact that the average profitable trade is so much more than the average loss on a non-profitable trade makes this strategy a winner. Now this is using the standard parameters for all stocks. I see you've tried to adjust the parameters for one stock but I have yet to try that. Also would be interesting to see the impact on profits by adjusting the parameters and seeing if 1-minute, 2-minute or 3-minute bars are best.
 
H

heramone

New member
VIP
Are you talking about 3 SuperTrend + Support and Resistance Level Strategy for ThinkorSwim? Could you please help me to work on my chart. I used TOS, but after adding this strategy no change in my chart and no signal appear anywhyre.. Please help me with correct script so that I can get benefited with. Thanks
 
YungTraderFromMontana

YungTraderFromMontana

Well-known member
Checking out this strat again. I'm also converting to a longer term version. @Midtown Mo could you do one of those cool scans on a 4h version of this when I finish it?
 
YungTraderFromMontana

YungTraderFromMontana

Well-known member
@Midtown Mo It would be awesome to see the data of this run on the 2h. I'd expect from looking around to see it being profitable on 80% of stocks with amazing margins on some. I've found some individual stocks with 2/3 win rates and 3/1 win size/loss size ratio.
Code:
#3-SuperTrend & HighLow Strategy by RConner7
#includes Backtesting utility results from eddielee394
#2 min time frame but could 3 ST ATRs and High/Low lookbackPeriod can be adjusted.
#----------------------------
#def atr1 = atr();
#def atr2 = atr() * 2;
#def atr3 = atr() * 3;
 def SDmult = 2.3;
def ATRmult9 = 1.3;
def lengthsqu = 5;
input AlertOn  = yes;
input AtrMult = 1.0;

input nATR = 4;

input AvgType = AverageType.ExpONENTIAL;

input AtrMult_2 = 1.2;

input nATR_2 = 4;

input AvgType_2 = AverageType.WeIGHTED;

input AtrMult_3 = 2.9;

input nATR_3 = 5;

input AvgType_3 = AverageType.ExPONENTIAL;

input PaintBars = yes;

input BubbleOn = yes;

input ShowLabel = yes;
#SMIExtreme
input audioalarm = yes;
input Price = hlc3;
input RsqLength = 5;
input RsqLimit = .5;
input SmiLimit = 30;
input chopband2 = 70;
input smibarbufr = 4;
input showBreakoutSignals = yes;

plot upper = 70;
plot lower = -70;

def overbought = SmiLimit;
def oversold = -SmiLimit;
def percentDLength = 4;
def percentKLength = 5;

#Stochastics

input over_bought = 80;
input over_sold = 20;
input KPeriod = 12;
input DPeriod = 7;
input priceH = high;
input priceL = low;
input priceC = close;
input averageType = AverageType.EXPONENTIAL;

input lengthmo = 12;

def price7 = (open + close)/2;



def K = (Highest(high, lengthmo) + Lowest(low, lengthmo)) /
               2 + ExpAverage(close, lengthmo);
def Momo = Inertia(price7 - K / 2, lengthmo);

def SD = StDev(close, lengthsqu);
def Avg = ExpAverage(close, lengthsqu);
def ATRb = Average(TrueRange(high, close, low), lengthsqu);
def SDup = Avg + (SDmult * SD);
def ATRup = Avg + (ATRmult9 * ATRb);
def Squeeze3 = SDup < ATRup;


def SlowK = reference StochasticFull(over_bought, over_sold, KPeriod, DPeriod, priceH, priceL, priceC, 3, averageType).FullK;
def SlowD = reference StochasticFull(over_bought, over_sold, KPeriod, DPeriod, priceH, priceL, priceC, 3, averageType).FullD;

def badgood = (slowd crosses above slowk);

#ATRBreakout
input BuyEntry = 3;
input SellEntry = 3;

def QB = Highest(high, BuyEntry);
def QS = Lowest(low, SellEntry);
plot trueqb = QB[1];
plot trueqs = QS[1];
plot midline = (QB[1] + QS[1]) / 2;
plot sellline = ((QB[1] * 3) + (QS[1] * 2)) / 5;
plot buyline = ((QS[1] * 3) + (QB[1]) * 2) / 5;


input lengthn = 49;

def lProjection = reference TimeSeriesForecast(price = Price, length = lengthn, "bar plus" = 1);
def convolutionLength = Floor(Sqrt(lengthn));

def LeavittConvolutionSlope = reference LinearRegressionSlope(price = lProjection, length = convolutionLength);
def squeeze = (LeavittConvolutionSlope > .01) or (LeavittConvolutionSlope < -.01);

#def beginDay = if barNumber() < nATR then barNumber() else nATR;

def h = high;

def l = low;

def c = close;

def v = volume;

def bar = BarNumber();

def CloseAllCondition = CLOSE > 600000;

def EOD = close > 600000;

def NotActive = close > 6000000;

def Active1 = close < 60000;

def notrades = close > 60000000;

def ATR = MovingAverage(AvgType, TrueRange(h, c, l), nATR);
def UP_Band_Basic = HL2 + (AtrMult * ATR);

def LW_Band_Basic = HL2 + (-AtrMult * ATR);

def UP_Band = if Active1 and ((UP_Band_Basic < UP_Band[1]) or (close[1] > UP_Band[1])) then UP_Band_Basic else UP_Band[1];

def LW_Band = if Active1 and ((LW_Band_Basic > LW_Band[1]) or (close[1] < LW_Band[1])) then LW_Band_Basic else LW_Band[1];

def ST = if Active1 and ((ST[1] == UP_Band[1]) and (close < UP_Band)) then UP_Band else if ((ST[1] == UP_Band[1]) and (close > UP_Band)) then LW_Band else if ((ST[1] == LW_Band[1]) and (close > LW_Band)) then LW_Band else if ((ST[1] == LW_Band) and (close < LW_Band)) then UP_Band else LW_Band;

plot SuperTrend = ST;

SuperTrend.AssignValueColor(if c < ST then Color.RED else Color.GREEN);

SuperTrend.SetPaintingStrategy(PaintingStrategy.LINE);

AssignPriceColor(if PaintBars and c < ST

                 then Color.RED

                 else if PaintBars and c > ST

                      then Color.GREEN

                      else Color.CURRENT);

#ST2


input PaintBars_2 = no;

input BubbleOn_2 = no;

input ShowLabel_2 = no;

def beginDay_2 = if BarNumber() < nATR_2 then BarNumber() else nATR_2;


def Active_2 = close < 600000;

def ATR_2 = MovingAverage(AvgType_2, TrueRange(h, c, l), nATR_2);
def UP_Band_Basic_2 = HL2 + (AtrMult_2 * ATR_2);

def LW_Band_Basic_2 = HL2 + (-AtrMult_2 * ATR_2);

def UP_Band_2 = if Active_2 and ((UP_Band_Basic_2 < UP_Band_2[1]) or (close[1] > UP_Band_2[1])) then UP_Band_Basic_2 else UP_Band_2[1];

def LW_Band_2 = if Active_2 and ((LW_Band_Basic_2 > LW_Band_2[1]) or (close[1] < LW_Band_2[1])) then LW_Band_Basic_2 else LW_Band_2[1];

def ST_2 = if Active_2 and ((ST_2[1] == UP_Band_2[1]) and (close < UP_Band_2)) then UP_Band_2 else if ((ST_2[1] == UP_Band_2[1]) and (close > UP_Band_2)) then LW_Band_2 else if ((ST_2[1] == LW_Band_2[1]) and (close > LW_Band_2)) then LW_Band_2 else if ((ST_2[1] == LW_Band_2) and (close < LW_Band_2)) then UP_Band_2 else LW_Band_2;


plot SuperTrend_2 = ST_2;

SuperTrend_2.AssignValueColor(if c < ST_2 then Color.RED else Color.GREEN);

SuperTrend_2.SetPaintingStrategy(PaintingStrategy.LINE);

AssignPriceColor(if PaintBars_2 and c < ST_2

                 then Color.RED

                 else if PaintBars_2 and c > ST_2

                      then Color.GREEN

                      else Color.CURRENT);

#ST3



input PaintBars_3 = no;

input BubbleOn_3 = no;

input ShowLabel_3 = no;

#def beginDay_3 = if barNumber() < nATR_3 then barNumber() else nATR_3;


def Active_3 = close < 60000000;

def ATR_3 = MovingAverage(AvgType_3, TrueRange(h, c, l), nATR_3);
def UP_Band_Basic_3 = HL2 + (AtrMult_3 * ATR_3);

def LW_Band_Basic_3 = HL2 + (-AtrMult_3 * ATR_3);

def UP_Band_3 = if Active_3 and ((UP_Band_Basic_3 < UP_Band_3[1]) or (close[1] > UP_Band_3[1])) then UP_Band_Basic_3 else UP_Band_3[1];

def LW_Band_3 = if Active_3 and ((LW_Band_Basic_3 > LW_Band_3[1]) or (close[1] < LW_Band_3[1])) then LW_Band_Basic_3 else LW_Band_3[1];

def ST_3 = if Active_3 and ((ST_3[1] == UP_Band_3[1]) and (close < UP_Band_3)) then UP_Band_3 else if ((ST_3[1] == UP_Band_3[1]) and (close > UP_Band_3)) then LW_Band_3 else if ((ST_3[1] == LW_Band_3[1]) and (close > LW_Band_3)) then LW_Band_3 else if ((ST_3[1] == LW_Band_3) and (close < LW_Band_3)) then UP_Band_3 else LW_Band_3;

plot SuperTrend_3 = ST_3;

SuperTrend_3.AssignValueColor(if c < ST_3 then Color.RED else Color.GREEN);

SuperTrend_3.SetPaintingStrategy(PaintingStrategy.LINE);

AssignPriceColor(if PaintBars_3 and c < ST_3

                 then Color.RED

                 else if PaintBars_3 and c > ST_3

                      then Color.GREEN

                      else Color.CURRENT);

#VWAP
def VWAP = if open > reference VWAP()."VWAP" then 1 else 0;

#Money Flow Index
#input MFI_length = 10;
#input MFI_movingAvgLength = 2;

#def MFI = Average(moneyflow(high, close, low, volume, MFI_length), #MFI_movingAvgLength);


#ADX
#input ADXlength = 14;
#input ADXaverageType = AverageType.WILDERS;

#def ADX = DMI(ADXlength, ADXaverageType).ADX;
#def ADX_Trend = if ADX >= 25 then 1 else 0;

#swing high low
input LookbackPeriod = 2;
input HideCurrentTF = no;

def FirstBar = BarNumber();
def Highest = fold i = 1
             to LookbackPeriod + 1
             with p = 1
             while p
             do high > GetValue(high, -i);
def A = if (FirstBar > LookbackPeriod
            and high == Highest(high, LookbackPeriod)
            and Highest)
            then high
            else Double.NaN;
def Lowest = fold j = 1
            to LookbackPeriod + 1
            with q = 1
            while q
            do low < GetValue(low, -j);
def B = if (FirstBar > LookbackPeriod
            and low == Lowest(low, LookbackPeriod)
            and Lowest)
            then low
            else Double.NaN;

#--------------------------------------------------------------
def _highInPeriod1 = Highest(high, LookbackPeriod);
def _lowInPeriod1 = Lowest(low, LookbackPeriod);
#--------------------------------------------------------------
def marketLow1 = if _lowInPeriod1 < _lowInPeriod1[-LookbackPeriod] then _lowInPeriod1 else _lowInPeriod1[-LookbackPeriod];
def _markedLow1 = low == marketLow1;

rec _lastMarkedLow1 = CompoundValue(1, if IsNaN(_markedLow1) then _lastMarkedLow1[1] else if _markedLow1 then low else _lastMarkedLow1[1], low);
#--------------------------------------------------------------
def marketHigh1 = if _highInPeriod1 > _highInPeriod1[-LookbackPeriod] then _highInPeriod1 else _highInPeriod1[-LookbackPeriod];
def _markedHigh1 = high == marketHigh1;

rec _lastMarkedHigh1 = CompoundValue(1, if IsNaN(_markedHigh1) then _lastMarkedHigh1[1] else if _markedHigh1 then high else _lastMarkedHigh1[1], high);
#--------------------------------------------------------------

plot Resistance1 = _lastMarkedHigh1;
plot Support1 = _lastMarkedLow1;

#---------------------------------------
plot ph = Round(A, 2);
ph.SetPaintingStrategy(PaintingStrategy.VALUES_ABOVE);
plot pl = Round(B, 2);
pl.SetPaintingStrategy(PaintingStrategy.VALUES_BELOW);
#--------------------------------------------------------------
Resistance1.SetPaintingStrategy(PaintingStrategy.DASHES);
Resistance1.SetDefaultColor(Color.GREEN);
Resistance1.SetHiding(HideCurrentTF);
#--------------------------------------------------------------
Support1.SetPaintingStrategy(PaintingStrategy.DASHES);
Support1.SetDefaultColor(Color.RED);
Support1.SetHiding(HideCurrentTF);

#Bull

def ni = (open + close)/2;
def fast_ST_UP = if ni > ST then 1 else 0;
def slow_ST_UP = if ni > ST_2 then 1 else 0;
def slower_ST_UP = if ni > ST_3 then 1 else 0;
def any_UP = fast_ST_UP or slower_ST_UP;
def Trend_UP = if ni > ST then 1 else 0;
def Trend_UP_2 = if ni > ST_2 then 1 else 0;
def Trend_UP_3 = if ni > ST_3 then 1 else 0;
def Trend_UP_ALL = Trend_UP and Trend_UP_3;
def higher_close = if close crosses above Resistance1[1] then 1 else 0;
def candle = ((open + close) / 2);
#Bear
def fast_ST_DN = if HL2 < ST then 1 else 0;
def slow_ST_DN = if HL2 < ST_2 then 1 else 0;
def slower_ST_DN = if HL2 < ST_3 then 1 else 0;
def any_DN = fast_ST_DN or slower_ST_DN;
def Trend_DN = if HL2 < ST then 1 else 0;
def Trend_DN_2 = if HL2 < ST_2 then 1 else 0;
def Trend_DN_3 = if HL2 < ST_3 then 1 else 0;
def Trend_DN_ALL = Trend_DN and Trend_DN_3;
def lower_close = if close crosses below Support1[1] then 1 else 0;
plot middleST = (hl2[1] + ST_3[1])/2;
def fg = (high - close) < ((close - open) * 2);
def fgbear = (close-low) < ((open - close) * 2);
def goodcandle = ((high - close) < (hl2 - low)) or (open > high[1]);
def goodsellcandle = (close - low) < (high - hl2);

AddOrder(OrderType.BUY_AUTO, (any_UP) and Trend_UP_ALL and (higher_close or higher_close[1] or higher_close[2]), price = close, tickcolor = Color.ORANGE, arrowcolor = Color.ORANGE, name = "BUY");

AddOrder(OrderType.SELL_TO_CLOSE, (candle crosses below ST_2), price = open[-1], tickcolor = Color.ORANGE, arrowcolor = Color.ORANGE, name = "Sell To Close");

AddOrder(OrderType.SELL_AUTO, (any_DN) and Trend_DN_ALL and (lower_close or lower_close[1] or lower_close[2])  , price = close, tickcolor = Color.YELLOW, arrowcolor = Color.YELLOW, name = "SELL");

AddOrder(OrderType.BUY_TO_CLOSE, (candle crosses above ST_2 ), price = open[-1], tickcolor = Color.ORANGE, arrowcolor = Color.ORANGE, name = "Buy To Close");



Alert((fast_ST_UP or slow_ST_UP or slower_ST_UP) and Trend_UP and Trend_UP_2 and Trend_UP_3 and Active1 and higher_close and notrades, "BUY BUY BUY", Alert.BAR, Sound.Bell);
Alert((fast_ST_DN or slow_ST_DN or slower_ST_DN) and Trend_DN and Trend_DN_2 and Trend_DN_3  and Active1 and lower_close and notrades, "SELL SELL SELL", Alert.BAR, Sound.Ring);

############################
# 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
);
 
S

santanu1477

New member
Hi There, I have a similar question as heramone.

I have added the code as a new study in TOS (Mac desktop app), but nothing changes to the chart (30day-2min. tried other as well). I understand that it can be a rookie like question, but would highly appreciate if someone may advice what could be going wrong here.
 
C

cfw238

New member
This strategy is very attracting as it gives pretty accurate trend reversal on lowertimeframe. Thank you
 
B

Bobby

New member
VIP
@YungTraderFromMontana I am currently trying to set up your more long term code for this strategy on the 20 day 1 hour chart and I was wondering if there are any settings you would recommend changing and what to change if I wanted to use it on the 15 minute chart for day trading? Thank you for your help.
 
B

Bobby

New member
VIP
@RConner7 Maybe you would know too? Although I know you originally wrote your version for the 2 min chart is there a good way to convert it to the 5 day 15 min or 20 day 1 hour?
 
I

irishgold

Member
Reviewing this strategy, I found an interesting value in using option call tickers in TOS like .APPL200529C315 , turning off the sell side and adjusting number of contracts to 10 instead of the Auto (100). ON 30Min The calls do very well just tracking the option graph. I'm going to experiment next week with this idea. Doing AAPL shares (100), BUY only, same time interval much less money and far more risk. Maybe some kind of hybrid of using the BUY signals on the AAPL chart and buy option calls instead. Just a thought.
Edited: By adding to the Buy_To_Open Volume > Average(Volume,50) I got better results.
 
Last edited:
T

T-Chart

New member
Sorry if I'm missed it but what are the entry rules for this strategy? Buy or Short on the breakouts?
 
D

dmaffo

New member
VIP
Hello All - I've been working on a strategy that incorporates a 3 SuperTrend (yahoo finance version) (fast, medium, slow) + previous Support and Resistance levels. Essentially what the strategy does is lookback to find the previous high and low. If price close breaks the previous high and all 3 supertrends are green, it will indicate a buy signal. opposite for short trades.

I'm looking for some feedback on this strategy to see what can be done to make it better and more dynamic based on the stock you are trading. - or really... if it sucks... tell me why.

I've been testing this with the below settings on BA (Boeing) from a 2 minute time frame for the past 30 days and seeing very decent results with 100 share trade lots. [see below] I have found that the strategy will work for different stocks as well but has varying results. Results will vary based upon the atr lengths and lookbacks for each supertrend. (would be looking for help figuring out a way to make this dynamic if possible. - Finding a way to calculate and set these based on a variable from the selected stock)

--code still includes some things i was playing around with but unused stuff is commented out--

Code:
#3-SuperTrend & HighLow Strategy by RConner7
#includes Backtesting utility results from eddielee394
#2 min time frame but could 3 ST ATRs and High/Low lookbackPeriod can be adjusted.
#----------------------------
#def atr1 = atr();
#def atr2 = atr() * 2;
#def atr3 = atr() * 3;

input AlertOn  = yes;
input AtrMult = .70;

input nATR = 4;

input AvgType = AverageType.HULL;

input PaintBars = yes;

input BubbleOn = yes;

input ShowLabel = yes;

#def beginDay = if barNumber() < nATR then barNumber() else nATR;

def h = high;

def l = low;

def c = close;

def v = volume;

def bar = BarNumber();

def CloseAllCondition = SecondstillTime(1558) == 0;

def EOD = if SecondsTillTime(1558) == 0 and

             SecondsFromTime(1558) == 0

          then 1

          else 0;

def NotActive = if SecondsFromTime(1550) > 0

                then 1

                else 0;

def Active1 = if SecondsFromTime(0930) > 0 then 1 else 0;

def notrades = if SecondstillTime(1500) > 0 then 1 else 0;

def ATR = MovingAverage(AvgType, TrueRange(h, c, l), nAtr);
def UP_Band_Basic = HL2 + (AtrMult * ATR);

def LW_Band_Basic = HL2 + (-AtrMult * ATR);

def UP_Band = if Active1 and ((UP_Band_Basic < UP_Band[1]) or (close[1] > UP_Band[1])) then UP_Band_Basic else UP_Band[1];

def LW_Band = if Active1 and ((LW_Band_Basic > LW_Band[1]) or (close[1] < LW_Band[1])) then LW_Band_Basic else LW_Band[1];

def ST = if Active1 and ((ST[1] == UP_Band[1]) and (close < UP_Band)) then UP_Band else if ((ST[1] == UP_Band[1]) and (close > Up_Band)) then LW_Band else if ((ST[1] == LW_Band[1]) and (close > LW_Band)) then LW_Band else if ((ST[1] == LW_Band) and (close < LW_Band)) then UP_Band else LW_Band;

plot SuperTrend = ST;

SuperTrend.AssignValueColor(if c < ST then Color.RED else Color.GREEN);

SuperTrend.SetPaintingStrategy(PaintingStrategy.LINE);

AssignPriceColor(if PaintBars and c < ST

                 then Color.RED

                 else if PaintBars and c > ST

                      then Color.GREEN

                      else Color.CURRENT);

#ST2

input AtrMult_2 = 1.5;

input nATR_2 = 3;

input AvgType_2 = AverageType.HULL;

input PaintBars_2 = no;

input BubbleOn_2 = no;

input ShowLabel_2 = no;

def beginDay_2 = if barNumber() < nATR_2 then barNumber() else nATR_2;


def Active_2 = if SecondsFromTime(0930) > 0  then 1 else 0;

def ATR_2 = MovingAverage(AvgType_2, TrueRange(h, c, l), nAtr_2);
def UP_Band_Basic_2 = HL2 + (AtrMult_2 * ATR_2);

def LW_Band_Basic_2 = HL2 + (-AtrMult_2 * ATR_2);

def UP_Band_2 = if Active_2 and ((UP_Band_Basic_2 < UP_Band_2[1]) or (close[1] > UP_Band_2[1])) then UP_Band_Basic_2 else UP_Band_2[1];

def LW_Band_2 = if Active_2 and ((LW_Band_Basic_2 > LW_Band_2[1]) or (close[1] < LW_Band_2[1])) then LW_Band_Basic_2 else LW_Band_2[1];

def ST_2= if Active_2 and ((ST_2[1] == UP_Band_2[1]) and (close < UP_Band_2)) then UP_Band_2 else if ((ST_2[1] == UP_Band_2[1]) and (close > Up_Band_2)) then LW_Band_2 else if ((ST_2[1] == LW_Band_2[1]) and (close > LW_Band_2)) then LW_Band_2 else if ((ST_2[1] == LW_Band_2) and (close < LW_Band_2)) then UP_Band_2 else LW_Band_2;


plot SuperTrend_2 = ST_2;

SuperTrend_2.AssignValueColor(if c < ST_2 then Color.RED else Color.GREEN);

SuperTrend_2.SetPaintingStrategy(PaintingStrategy.LINE);

AssignPriceColor(if PaintBars_2 and c < ST_2

                 then Color.RED

                 else if PaintBars_2 and c > ST_2

                      then Color.GREEN

                      else Color.CURRENT);

#ST3

input AtrMult_3 = 3.0;

input nATR_3 = 5;

input AvgType_3 = AverageType.HULL;

input PaintBars_3 = no;

input BubbleOn_3 = no;

input ShowLabel_3 = no;

#def beginDay_3 = if barNumber() < nATR_3 then barNumber() else nATR_3;


def Active_3 = if SecondsFromTime(0930) > 0  then 1 else 0;

def ATR_3 = MovingAverage(AvgType_3, TrueRange(h, c, l), nAtr_3);
def UP_Band_Basic_3 = HL2 + (AtrMult_3 * ATR_3);

def LW_Band_Basic_3 = HL2 + (-AtrMult_3 * ATR_3);

def UP_Band_3 = if Active_3 and ((UP_Band_Basic_3 < UP_Band_3[1]) or (close[1] > UP_Band_3[1])) then UP_Band_Basic_3 else UP_Band_3[1];

def LW_Band_3 = if Active_3 and ((LW_Band_Basic_3 > LW_Band_3[1]) or (close[1] < LW_Band_3[1])) then LW_Band_Basic_3 else LW_Band_3[1];

def ST_3= if Active_3 and ((ST_3[1] == UP_Band_3[1]) and (close < UP_Band_3)) then UP_Band_3 else if ((ST_3[1] == UP_Band_3[1]) and (close > Up_Band_3)) then LW_Band_3 else if ((ST_3[1] == LW_Band_3[1]) and (close > LW_Band_3)) then LW_Band_3 else if ((ST_3[1] == LW_Band_3) and (close < LW_Band_3)) then UP_Band_3 else LW_Band_3;

plot SuperTrend_3 = ST_3;

SuperTrend_3.AssignValueColor(if c < ST_3 then Color.RED else Color.GREEN);

SuperTrend_3.SetPaintingStrategy(PaintingStrategy.LINE);

AssignPriceColor(if PaintBars_3 and c < ST_3

                 then Color.RED

                 else if PaintBars_3 and c > ST_3

                      then Color.GREEN

                      else Color.CURRENT);

#VWAP
def VWAP = if open > reference VWAP()."VWAP" then 1 else 0;

#Money Flow Index
#input MFI_length = 10;
#input MFI_movingAvgLength = 2;

#def MFI = Average(moneyflow(high, close, low, volume, MFI_length), #MFI_movingAvgLength);


#ADX
#input ADXlength = 14;
#input ADXaverageType = AverageType.WILDERS;

#def ADX = DMI(ADXlength, ADXaverageType).ADX;
#def ADX_Trend = if ADX >= 25 then 1 else 0;

#swing high low
input LookbackPeriod = 2;
input HideCurrentTF = no;

def FirstBar = BarNumber();
def Highest = fold i = 1
             to LookbackPeriod + 1
             with p = 1
             while p
             do high > GetValue(high, -i);
def A = if (Firstbar > LookbackPeriod
            and high == Highest(high, LookbackPeriod)
            and Highest)
            then high
            else Double.NaN;
def Lowest = fold j = 1
            to LookbackPeriod + 1
            with q = 1
            while q
            do low < GetValue(low, -j);
def B = if (Firstbar > LookbackPeriod
            and low == Lowest(low, LookbackPeriod)
            and Lowest)
            then low
            else Double.NaN;

#--------------------------------------------------------------
def _highInPeriod1 = Highest(high, LookbackPeriod);
def _lowInPeriod1 = Lowest(low, LookbackPeriod);
#--------------------------------------------------------------
def marketLow1 = if _lowInPeriod1 < _lowInPeriod1[-LookbackPeriod] then _lowInPeriod1 else _lowInPeriod1[-LookbackPeriod];
def _markedLow1 = low == marketLow1;

rec _lastMarkedLow1 = CompoundValue(1, if IsNaN(_markedLow1) then _lastMarkedLow1[1] else if _markedLow1 then low else _lastMarkedLow1[1], low);
#--------------------------------------------------------------
def marketHigh1 = if _highInPeriod1 > _highInPeriod1[-LookbackPeriod] then _highInPeriod1 else _highInPeriod1[-LookbackPeriod];
def _markedHigh1 = high == marketHigh1;

rec _lastMarkedHigh1 = CompoundValue(1, if IsNaN(_markedHigh1) then _lastMarkedHigh1[1] else if _markedHigh1 then high else _lastMarkedHigh1[1], high);
#--------------------------------------------------------------

plot Resistance1 = _lastMarkedHigh1;
plot Support1 = _lastMarkedLow1;

#---------------------------------------
plot ph = Round(A, 2);
ph.SetPaintingStrategy(PaintingStrategy.VALUES_ABOVE);
plot pl = Round(B, 2);
pl.SetPaintingStrategy(PaintingStrategy.VALUES_BELOW);
#--------------------------------------------------------------
Resistance1.SetPaintingStrategy(PaintingStrategy.DASHES);
Resistance1.SetDefaultColor(Color.GREEN);
Resistance1.SetHiding(HideCurrentTF);
#--------------------------------------------------------------
Support1.SetPaintingStrategy(PaintingStrategy.DASHES);
Support1.SetDefaultColor(Color.RED);
Support1.SetHiding(HideCurrentTF);

#Bull
def fast_ST_UP = if HL2 > ST then 1 else 0;
def slow_ST_UP = if HL2 > ST_2 then 1 else 0;
def slower_ST_UP = if HL2 > ST_3 then 1 else 0;
def Trend_UP = if HL2 > ST then 1 else 0;
def Trend_UP_2 = if HL2 > ST_2 then 1 else 0;
def Trend_UP_3 = if HL2 > ST_3 then 1 else 0;
def higher_close = if close crosses above Resistance1[1] then 1 else 0;

#Bear
def fast_ST_DN = if HL2 < ST then 1 else 0;
def slow_ST_DN = if HL2 < ST_2 then 1 else 0;
def slower_ST_DN = if HL2 < ST_3 then 1 else 0;
def Trend_DN = if HL2 < ST then 1 else 0;
def Trend_DN_2 = if HL2 < ST_2 then 1 else 0;
def Trend_DN_3 = if HL2 < ST_3 then 1 else 0;
def lower_close = if close crosses below support1[1] then 1 else 0;

AddOrder(OrderType.BUY_AUTO, (fast_sT_UP or slow_ST_UP or slower_ST_UP) and Trend_Up and Trend_Up_2 and Trend_UP_3 and Active1 and higher_close and notrades, price = close, tickcolor = Color.ORANGE, arrowcolor = Color.ORANGE, name = "BUY");

AddOrder(OrderType.Sell_To_Close, HL2 crosses below ST, price = open[-1], tickcolor = Color.ORANGE, arrowcolor = Color.ORANGE, name = "Sell To Close");


AddOrder(OrderType.Sell_TO_CLOSE, EOD or closeAllCondition, price = close, tickcolor = Color.ORANGE, arrowcolor = Color.ORANGE, name = "SELL EOD");

AddOrder(OrderType.SELL_AUTO, (fast_sT_DN or slow_ST_DN or slower_ST_DN) and Trend_DN and Trend_DN_2 and Trend_DN_3  and Active1 and lower_close and notrades , price = close, tickcolor = Color.YELLOW, arrowcolor = Color.YELLOW, name = "SELL");

AddOrder(OrderType.Buy_To_Close, HL2 crosses above ST, price = open[-1], tickcolor = Color.ORANGE, arrowcolor = Color.ORANGE, name = "Buy To Close");

AddOrder(OrderType.BUY_TO_CLOSE, EOD or closeAllCondition, price = close, tickcolor = Color.ORANGE, arrowcolor = Color.ORANGE, name = "BUY EOD");

alert((fast_sT_UP or slow_ST_UP or slower_ST_UP) and Trend_Up and Trend_Up_2 and Trend_UP_3 and Active1 and higher_close and notrades, "BUY BUY BUY", Alert.Bar, Sound.Bell);
alert((fast_sT_DN or slow_ST_DN or slower_ST_DN) and Trend_DN and Trend_DN_2 and Trend_DN_3  and Active1 and lower_close and notrades, "SELL SELL SELL", Alert.Bar, Sound.Ring);

############################
# 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
);

Is this script still working? I tried installing on TOS a few mins ago and nothing changed on charts. Thanks
 
murkr

murkr

Member
VIP
@YungTraderFromMontana are you still using this strategy?

@dmaffo you have to add it as a "strategy" not a "study"
 
B

Bruce lee

New member
Hi, can you make an automatic support resistance line when for example, a choice of 500% volume change in the Ask. Thanks
 

Similar threads

Top