Repaints 5 min MTF Futures Setup

Repaints

JoeDV

Active member
VIP
Every now and then I like to share whatever setup I'm currently using. I'm sure I borrowed code from others, just don't ask me who. At my age, I believe I've given more than I've taken over the years but I still appreciate others work and effort, so thank you!

This is the setup I've been using for mostly Soybeans, but have also been using it for live cattle and a couple others. It looks odd but though it's a 5 min chart, leave the time frame at 30 mins in the study. I've enjoyed it quite a bit. Not likely to give you the big hitters, but also doesn't get a lot of big losers. Kind of the game I play with futures in general, more than happy with average consistent returns.

Feel free to play around, but as always, this isn't investment advice, nor should you play around with futures if you're not experienced. (especially if you're married) :)

Edit: Oh, last week someone saw my setup for trading and was asking if that's all I used, just some arrows, no multiple lines all over, no 15 different indicators, nothing, just what you see. The answer is yes, it's a pet peeve of mine when I see charts with so much duplicative stuff just different indicators. Keep it simple and you'll enjoy trading a whole lot more.

Screenshot 2025-03-14 162129.jpg


Top Chart only
Code:
# Trend Angle with Volatility Filter and Zero Lag MA

# Calculates the angle of a zero-lag moving average line, using a volatility
# filter and up/down day count to generate buy/sell signals.

# Inputs
input timeFrame = AggregationPeriod.THIRTY_MIN;
input fastMALength = 20;
input slowMALength = 50;
input volatilityLookBack = 50;
input upDownLookback = 15;

# Zero Lag MA Calculation
script ZeroLagMA {
    input price = close;
    input length = 20;
    input maType = AverageType.EXPONENTIAL;

    def lag = Floor((length - 1) / 2);
    def zlBasis = if maType == AverageType.EXPONENTIAL then
        ExpAverage(2 * price - price[lag], length)
    else
        Average(2 * price - price[lag], length);

    plot ZLMA = zlBasis;
}

def fastZLMA = ZeroLagMA(price = close(period = timeFrame), length = fastMALength).ZLMA;
def slowZLMA = ZeroLagMA(price = close(period = timeFrame), length = slowMALength).ZLMA;
def midZLMA = (fastZLMA + slowZLMA) / 2;

# Volatility Calculation
script Volatility {
    input price = close;
    input lookbackDays = 10;

    def dailyChange = AbsValue(price - price[1]);
    def avgDailyChange = Average(dailyChange, lookbackDays);

    plot Volatility = avgDailyChange;
}

def volatility = Volatility(price = close(period = timeFrame), lookbackDays = volatilityLookBack).Volatility * 1.5;

# Up/Down Days Count
script UpDownDaysCount {
    input lookbackDays = 15;
    input price = close;

    def upDays = Sum(if price > price[1] then 1 else 0, lookbackDays);
    def downDays = Sum(if price < price[1] then 1 else 0, lookbackDays);

    plot Difference = upDays - downDays;
}

def diff = UpDownDaysCount(lookbackDays = upDownLookback).Difference;

# Trend Angle Calculation
def rise = midZLMA - midZLMA[2];
def run = 1;
def normalizedRise = rise / volatility;  # Use calculated volatility
def trendAngle = ATan(normalizedRise / run) * 180 / Double.Pi;
def TA = trendAngle;

# Signal Generation (Improved)
def isRising = trendAngle >= trendAngle[1] and trendAngle[1] > trendAngle[2]; # More concise
def isFalling = trendAngle <= trendAngle[1] and trendAngle[1] < trendAngle[2]; # More concise

#def BuySignal = isRising == 1 and trendAngle crosses above 0;
#def SellSignal = isFalling == 1 and trendAngle crosses below 0;
def BuySignal = isRising == 1 and trendAngle > 0;
def SellSignal = isFalling == 1 and trendAngle < 0;

def BuyStop = !isRising;
def SellStop = !isFalling;

###------------------------------------------------------------------------------------------
# Profit and Loss Labels
#
# Set two variables Buysignal and Sellsignal to your buy and sell signal conditions,
# or replace them below with your conditions
#
# When using large amounts of hisorical data, P/L may take time to calculate
###------------------------------------------------------------------------------------------

input showSignals = yes; #hint showSignals: show buy and sell arrows
input LongTrades = yes; #hint LongTrades: perform long trades
input ShortTrades = yes; #hint ShortTrades: perform short trades
input showLabels  = yes; #hint showLabels: show PL labels at top
input showBubbles = yes; #hint showBubbles: show PL bubbles at close of trade
input useStops = yes;     #hint useStops: use stop orders
input stopLimitDisplay = 0;  #hint stopLimit in dollars
input useAlerts = yes;    #hint useAlerts: use alerts on signals
input tradeDefinedHours = yes; #hint tradeDefinedHours:
input OpenTime = 1000; #hint OpenTime: Opening time of market
input CloseTime = 1400; #hint CloseTime: Closing time of market
input UseFuturesFees = no; #hint UseFutureFees: $6 round-trip

#Get actual trading time
def TradingHours = GetTime() between RegularTradingStart(GetYYYYMMDD()) and RegularTradingEnd(GetYYYYMMDD());

#Get time to do trading
def Begin = SecondsFromTime(OpenTime);
def End = SecondsTillTime(CloseTime);


# Only use market hours when using intraday timeframe
def isIntraDay = if GetAggregationPeriod() > 14400000 or GetAggregationPeriod() == 0 then 0 else 1;
def TradingWindow = if !tradeDefinedHours or !isIntraDay then 1 else if tradeDefinedHours and isIntraDay and Begin > 0 and End > 0 then 1 else 0;
###------------------------------------------------------------------------------------------

######################################################
##  Create Signals -
##  FILL IN THIS SECTION
##      replace 0>0 with your conditions for signals
######################################################

def PLBuySignal = if  TradingWindow and (Buysignal) then 1 else 0 ; # insert condition to create long position in place of the 0>0
def PLSellSignal =  if TradingWindow and (Sellsignal) then 1 else 0; # insert condition to create short position in place of the 0>0

def PLBuyStop  = if !useStops then 0 else if  (BuyStop) then 1 else 0  ; # insert condition to stop in place of the 0<0
def PLSellStop = if !useStops then 0 else if (SellStop) then 1 else 0  ; # insert condition to stop in place of the 0>0

def PLMktStop = if TradingWindow[-1] == 0 then 1 else 0; # If tradeDaytimeOnly is set, then stop at end of day


#######################################
##  Maintain the position of trades
#######################################

def CurrentPosition;  # holds whether flat = 0 long = 1 short = -1

if (BarNumber() == 1) or IsNaN(CurrentPosition[1]) {
    CurrentPosition = 0;
} else {
    if CurrentPosition[1] == 0 {            # FLAT
        if (PLBuySignal and LongTrades) {
            CurrentPosition = 1;
        } else if (PLSellSignal and ShortTrades) {
            CurrentPosition = -1;
        } else {
            CurrentPosition = CurrentPosition[1];
        }
    } else if CurrentPosition[1] == 1 {      # LONG
        if (PLSellSignal and ShortTrades) {
            CurrentPosition = -1;
        } else if ((PLBuyStop and useStops) or PLMktStop or (PLSellSignal and ShortTrades == 0)) {
            CurrentPosition = 0;
        } else {
            CurrentPosition = CurrentPosition[1];
        }
    } else if CurrentPosition[1] == -1 {     # SHORT
        if (PLBuySignal and LongTrades) {
            CurrentPosition = 1;
        } else if ((PLSellStop and useStops) or PLMktStop or (PLBuySignal and LongTrades == 0)) {
            CurrentPosition = 0;
        } else {
            CurrentPosition = CurrentPosition[1];
        }
    } else {
        CurrentPosition = CurrentPosition[1];
    }
}


def isLong  = if CurrentPosition == 1 then 1 else 0;
def isShort = if CurrentPosition == -1 then 1 else 0;
def isFlat  = if CurrentPosition == 0 then 1 else 0;

# If not already long and get a PLBuySignal
#Plot BuySig = if (!isLong[1] and PLBuySignal and showSignals and LongTrades) then 1 else 0;
plot BuySig = if (((isShort[1] and LongTrades) or (isFlat[1] and LongTrades)) and PLBuySignal and showSignals) then 1 else 0;
BuySig.AssignValueColor(Color.CYAN);
BuySig.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
BuySig.SetLineWeight(5);

Alert(BuySig and useAlerts, "Buy Signal", Alert.BAR, Sound.Chimes);
Alert(BuySig and useAlerts, "Buy Signal", Alert.BAR, Sound.Chimes);
Alert(BuySig and useAlerts, "Buy Signal", Alert.BAR, Sound.Chimes);
Alert(BuySig and useAlerts, "Buy Signal", Alert.BAR, Sound.Chimes);

# If not already short and get a PLSellSignal
plot SellSig = if (((isLong[1] and ShortTrades) or (isFlat[1] and ShortTrades)) and PLSellSignal and showSignals) then 1 else 0;
SellSig.AssignValueColor(Color.CYAN);
SellSig.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
SellSig.SetLineWeight(5);

Alert(SellSig and useAlerts, "Sell Signal", Alert.BAR, Sound.Chimes);
Alert(SellSig and useAlerts, "Sell Signal", Alert.BAR, Sound.Chimes);
Alert(SellSig and useAlerts, "Sell Signal", Alert.BAR, Sound.Chimes);
Alert(SellSig and useAlerts, "Sell Signal", Alert.BAR, Sound.Chimes);


# If long and get a PLBuyStop
plot BuyStpSig = if (PLBuyStop and isLong[1] and showSignals and useStops) or (isLong[1] and PLMktStop) or (isLong[1] and PLSellSignal and !ShortTrades) then 1 else 0;
BuyStpSig.AssignValueColor(Color.LIGHT_GRAY);
BuyStpSig.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
BuyStpSig.SetLineWeight(3);

Alert(BuyStpSig and useAlerts, "Buy Stop Signal", Alert.BAR, Sound.Ding);
Alert(BuyStpSig and useAlerts, "Buy Stop Signal", Alert.BAR, Sound.Ding);
Alert(BuyStpSig and useAlerts, "Buy Stop Signal", Alert.BAR, Sound.Ding);
Alert(BuyStpSig and useAlerts, "Buy Stop Signal", Alert.BAR, Sound.Ding);


# If short and get a PLSellStop
plot SellStpSig = if (PLSellStop and isShort[1] and showSignals and useStops) or (isShort[1] and PLMktStop) or (isShort[1] and PLBuySignal and !LongTrades) then 1 else 0;
SellStpSig.AssignValueColor(Color.LIGHT_GRAY);
SellStpSig.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
SellStpSig.SetLineWeight(3);

Alert(SellStpSig and useAlerts, "Sell Stop Signal", Alert.BAR, Sound.Ding);
Alert(SellStpSig and useAlerts, "Sell Stop Signal", Alert.BAR, Sound.Ding);
Alert(SellStpSig and useAlerts, "Sell Stop Signal", Alert.BAR, Sound.Ding);
Alert(SellStpSig and useAlerts, "Sell Stop Signal", Alert.BAR, Sound.Ding);


#######################################
##  Orders
#######################################

def isOrder = if ((isFlat[1] and (BuySig and LongTrades) or (SellSig and ShortTrades)) or (isLong[1] and BuyStpSig or (SellSig and ShortTrades)) or (isShort[1] and SellStpSig or (BuySig and LongTrades))) then 1 else 0 ;

def orderPrice = if (isOrder and ((BuySig and LongTrades) or (SellSig and ShortTrades))) then (if IsNaN(open[-1]) then close else open[-1]) else orderPrice[1];

plot OPL = if !isFlat and isLong then orderPrice else Double.NaN;
OPL.AssignValueColor(Color.GREEN);
OPL.SetPaintingStrategy(PaintingStrategy.LINE);
OPL.SetStyle(Curve.SHORT_DASH);
OPL.SetLineWeight(1);

#addcloud(OPL,close,color.red, color.green);

plot OPS = if !isFlat and isShort then orderPrice else Double.NaN;
OPS.AssignValueColor(Color.RED);
OPS.SetPaintingStrategy(PaintingStrategy.LINE);
OPS.SetStyle(Curve.SHORT_DASH);
OPS.SetLineWeight(1);

#addcloud(OPS,close,color.green, color.red);

def orderCount = CompoundValue(1, if IsNaN(isOrder) or BarNumber() == 1 then 0 else if (BuySig or SellSig) then orderCount[1] + 1 else orderCount[1], 0);


#######################################
##  Price and Profit
#######################################

def profitLoss;


if (!isOrder or orderPrice[1] == 0) {
    profitLoss = 0;
} else if ((isOrder and isLong[1]) and (SellSig or BuyStpSig)) {
    profitLoss = (if IsNaN(open[-1]) then close else open[-1]) - orderPrice[1];
} else if ((isOrder and isShort[1]) and (BuySig or SellStpSig)) {
    profitLoss = orderPrice[1] - (if IsNaN(open[-1]) then close else open[-1]);
} else {
    profitLoss = 0;
}


# Total Profit or Loss
def profitLossSum = CompoundValue(1, if IsNaN(isOrder)  or BarNumber() == 1 then 0 else if isOrder then profitLossSum[1] + profitLoss else profitLossSum[1], 0);

# How many trades won or lost
def profitWinners = CompoundValue(1, if IsNaN(profitWinners[1]) or BarNumber() == 1 then 0 else if isOrder and profitLoss > 0 then profitWinners[1] + 1 else profitWinners[1], 0);
def profitLosers = CompoundValue(1, if IsNaN(profitLosers[1])  or BarNumber() == 1 then 0 else if isOrder and profitLoss < 0 then profitLosers[1] + 1 else profitLosers[1], 0);
def profitPush = CompoundValue(1, if IsNaN(profitPush[1])  or BarNumber() == 1 then 0 else if isOrder and profitLoss == 0 then profitPush[1] + 1 else profitPush[1], 0);

# Current Open Trade Profit or Loss
def TradePL = if isLong then Round(((close - orderPrice) / TickSize()) * TickValue()) else if isShort then Round(((orderPrice - close) / TickSize()) * TickValue()) else 0;

# Convert to actual dollars based on Tick Value for bubbles
def dollarProfitLoss = if orderPrice[1] == 0 or IsNaN(orderPrice[1]) then 0 else Round((profitLoss / TickSize()) * TickValue());

# Closed Orders dollar P/L
def dollarPLSum = Round((profitLossSum / TickSize()) * TickValue());
def maxUpSum = CompoundValue(1, if IsNaN(maxUpSum[1]) or BarNumber() == 1 then 0 else if dollarPLSum > 0 and dollarPLSum > maxUpSum[1] then dollarPLSum else maxUpSum[1], 0);
def maxDnSum = CompoundValue(1, if IsNaN(maxDnSum[1]) or BarNumber() == 1 then 0 else if dollarPLSum < 0 and dollarPLSum < maxDnSum[1] then dollarPLSum else maxDnSum[1], 0);

# Split profits or losses by long and short trades
def profitLong = CompoundValue(1, if IsNaN(profitLong[1])  or BarNumber() == 1 then 0 else if isOrder and isLong[1] then profitLong[1] + dollarProfitLoss else profitLong[1], 0);
def profitShort = CompoundValue(1, if IsNaN(profitShort[1])  or BarNumber() == 1 then 0 else if isOrder and isShort[1] then profitShort[1] + dollarProfitLoss else profitShort[1], 0);
def countLong = CompoundValue(1, if IsNaN(countLong[1])  or BarNumber() == 1 then 0 else if isOrder and isLong[1] then countLong[1] + 1 else countLong[1], 0);
def countShort = CompoundValue(1, if IsNaN(countShort[1])  or BarNumber() == 1 then 0 else if isOrder and isShort[1] then countShort[1] + 1 else countShort[1], 0);

# What was the biggest winning and losing trade
def biggestWin = CompoundValue(1, if IsNaN(biggestWin[1]) or BarNumber() == 1 then 0 else if isOrder and (dollarProfitLoss > 0) and (dollarProfitLoss > biggestWin[1]) then dollarProfitLoss else biggestWin[1], 0);
def biggestLoss = CompoundValue(1, if IsNaN(biggestLoss[1]) or BarNumber() == 1 then 0 else if isOrder and (dollarProfitLoss < 0) and (dollarProfitLoss < biggestLoss[1]) then dollarProfitLoss else biggestLoss[1], 0);

def ClosedTradeCount = if (isLong or isShort) then orderCount - 1 else orderCount;
def OpenTrades = if (isLong or isShort) then 1 else 0;

def FuturesCommission = 8 * ClosedTradeCount;


# What percent were winners
def PCTWin = if (OpenTrades and (TradePL < 0)) then Round((profitWinners / (ClosedTradeCount + 1)) * 100, 2)
else if (OpenTrades and (TradePL > 0)) then Round(((profitWinners + 1) / (ClosedTradeCount + 1)) * 100, 2) else Round(((profitWinners) / (ClosedTradeCount)) * 100, 2) ;

# Average trade
def avgTrade = if (OpenTrades and (TradePL < 0)) then Round(((dollarPLSum - TradePL) / (ClosedTradeCount + 1)), 2)
else if (OpenTrades and (TradePL > 0)) then Round(((dollarPLSum + TradePL) / (ClosedTradeCount + 1)), 2) else Round(((dollarPLSum) / (ClosedTradeCount)), 2) ;


#######################################
##  Create Labels
#######################################


#AddLabel(showLabels and isIntraDay, if MarketOpen then "Market Open" else "Market Closed", Color.WHITE);
AddLabel(showLabels, if TradingHours then "Market Open" else "Market Closed", Color.WHITE);
AddLabel(showLabels and tradeDefinedHours, "Defined Hours", Color.WHITE);
AddLabel(showLabels and tradeDefinedHours, "Trade between: "+AsPrice(OpenTime)+" and "+AsPrice(CloseTime),Color.WHITE);
AddLabel(showLabels, GetSymbol() + " Tick Size: " + TickSize() + " Value: " + TickValue(), Color.WHITE);
AddLabel(showLabels and (LongTrades and ShortTrades), "Long+Short Trades", Color.WHITE);
AddLabel(showLabels and (LongTrades and !ShortTrades), "Long Trades Only", Color.WHITE);
AddLabel(showLabels and (!LongTrades and ShortTrades), "Short Trades Only", Color.WHITE);
AddLabel(showLabels and (UseFuturesFees), "Future Fees Incl", Color.WHITE);

AddLabel(showLabels, "Closed Orders: " + ClosedTradeCount + " P/L: " + AsDollars(dollarPLSum - if UseFuturesFees then FuturesCommission else 0), if dollarPLSum > 0 then Color.GREEN else if dollarPLSum < 0 then Color.RED else Color.GRAY);

AddLabel(if !IsNaN(orderPrice) and showLabels then 1 else 0, "Closed+Open P/L: " + AsDollars(TradePL + dollarPLSum - if UseFuturesFees then FuturesCommission else 0), if ((TradePL + dollarPLSum) > 0) then Color.GREEN else if ((TradePL + dollarPLSum - if UseFuturesFees then FuturesCommission else 0) < 0) then Color.RED else Color.GRAY);

AddLabel(showLabels, "Avg per Trade: " + AsDollars(avgTrade  - if UseFuturesFees then 6 else 0), if avgTrade > 0 then Color.GREEN else if avgTrade < 0 then Color.RED else Color.GRAY);
AddLabel(showLabels, "Winners: " + PCTWin + "%", if PCTWin > 50 then Color.GREEN else if PCTWin > 40 then Color.YELLOW else Color.GRAY);

AddLabel(showLabels, "Long Profit: " + AsDollars(profitLong), if profitLong > 0 then Color.GREEN else if profitLong < 0 then Color.RED else Color.GRAY);
AddLabel(showLabels, "Short Profit: " + AsDollars(profitShort), if profitShort > 0 then Color.GREEN else if profitShort < 0 then Color.RED else Color.GRAY);

AddLabel(showLabels, "MaxUpTrade: " + AsDollars(biggestWin) + " MaxDownTrade: " + AsDollars(biggestLoss), Color.WHITE);
AddLabel(showLabels, "MaxUpPL: " + AsDollars(maxUpSum) + " MaxDownPL: " + AsDollars(maxDnSum), Color.WHITE);

AddLabel(if !IsNaN(CurrentPosition) and showLabels and OpenTrades then 1 else 0, "Open: " + (if isLong then "Bought" else "Sold") + " @ " + orderPrice, Color.WHITE);
AddLabel(if !IsNaN(orderPrice) and showLabels and OpenTrades then 1 else 0, "Open Trade P/L: " + AsDollars(TradePL), if (TradePL > 0) then Color.GREEN else if (TradePL < 0) then Color.RED else Color.GRAY);

plot BuyStopLvl =  if isLong then OrderPrice - ((stopLimitDisplay/TickValue())*TickSize()) else double.nan;
plot ShortStopLvl =  if isShort then OrderPrice + ((stopLimitDisplay/TickValue())*TickSize()) else double.nan;
BuyStopLvl.AssignValueColor(Color.YELLOW);
BuyStopLvl.SetPaintingStrategy(PaintingStrategy.LINE);
BuyStopLvl.SetStyle(Curve.SHORT_DASH);
BuyStopLvl.SetLineWeight(1);
ShortStopLvl.AssignValueColor(Color.YELLOW);
ShortStopLvl.SetPaintingStrategy(PaintingStrategy.LINE);
ShortStopLvl.SetStyle(Curve.SHORT_DASH);
ShortStopLvl.SetLineWeight(1);

#######################################
##  Chart Bubbles for Profit/Loss
#######################################


AddChartBubble(showSignals and showBubbles and isOrder and isLong[1], low, "$" + dollarProfitLoss, if dollarProfitLoss == 0 then Color.LIGHT_GRAY else if dollarProfitLoss > 0 then Color.GREEN else Color.RED, 0);
AddChartBubble(showSignals and showBubbles and isOrder and isShort[1], high,  "$" + dollarProfitLoss, if dollarProfitLoss == 0 then Color.LIGHT_GRAY else if dollarProfitLoss > 0 then Color.GREEN else Color.RED, 1);

Full Setup
http://tos.mx/!9vSA1KZG
 
Every now and then I like to share whatever setup I'm currently using. I'm sure I borrowed code from others, just don't ask me who. At my age, I believe I've given more than I've taken over the years but I still appreciate others work and effort, so thank you!

This is the setup I've been using for mostly Soybeans, but have also been using it for live cattle and a couple others. It looks odd but though it's a 5 min chart, leave the time frame at 30 mins in the study. I've enjoyed it quite a bit. Not likely to give you the big hitters, but also doesn't get a lot of big losers. Kind of the game I play with futures in general, more than happy with average consistent returns.

Feel free to play around, but as always, this isn't investment advice, nor should you play around with futures if you're not experienced. (especially if you're married) :)

Edit: Oh, last week someone saw my setup for trading and was asking if that's all I used, just some arrows, no multiple lines all over, no 15 different indicators, nothing, just what you see. The answer is yes, it's a pet peeve of mine when I see charts with so much duplicative stuff just different indicators. Keep it simple and you'll enjoy trading a whole lot more.

View attachment 24289

Top Chart only
Code:
# Trend Angle with Volatility Filter and Zero Lag MA

# Calculates the angle of a zero-lag moving average line, using a volatility
# filter and up/down day count to generate buy/sell signals.

# Inputs
input timeFrame = AggregationPeriod.THIRTY_MIN;
input fastMALength = 20;
input slowMALength = 50;
input volatilityLookBack = 50;
input upDownLookback = 15;

# Zero Lag MA Calculation
script ZeroLagMA {
    input price = close;
    input length = 20;
    input maType = AverageType.EXPONENTIAL;

    def lag = Floor((length - 1) / 2);
    def zlBasis = if maType == AverageType.EXPONENTIAL then
        ExpAverage(2 * price - price[lag], length)
    else
        Average(2 * price - price[lag], length);

    plot ZLMA = zlBasis;
}

def fastZLMA = ZeroLagMA(price = close(period = timeFrame), length = fastMALength).ZLMA;
def slowZLMA = ZeroLagMA(price = close(period = timeFrame), length = slowMALength).ZLMA;
def midZLMA = (fastZLMA + slowZLMA) / 2;

# Volatility Calculation
script Volatility {
    input price = close;
    input lookbackDays = 10;

    def dailyChange = AbsValue(price - price[1]);
    def avgDailyChange = Average(dailyChange, lookbackDays);

    plot Volatility = avgDailyChange;
}

def volatility = Volatility(price = close(period = timeFrame), lookbackDays = volatilityLookBack).Volatility * 1.5;

# Up/Down Days Count
script UpDownDaysCount {
    input lookbackDays = 15;
    input price = close;

    def upDays = Sum(if price > price[1] then 1 else 0, lookbackDays);
    def downDays = Sum(if price < price[1] then 1 else 0, lookbackDays);

    plot Difference = upDays - downDays;
}

def diff = UpDownDaysCount(lookbackDays = upDownLookback).Difference;

# Trend Angle Calculation
def rise = midZLMA - midZLMA[2];
def run = 1;
def normalizedRise = rise / volatility;  # Use calculated volatility
def trendAngle = ATan(normalizedRise / run) * 180 / Double.Pi;
def TA = trendAngle;

# Signal Generation (Improved)
def isRising = trendAngle >= trendAngle[1] and trendAngle[1] > trendAngle[2]; # More concise
def isFalling = trendAngle <= trendAngle[1] and trendAngle[1] < trendAngle[2]; # More concise

#def BuySignal = isRising == 1 and trendAngle crosses above 0;
#def SellSignal = isFalling == 1 and trendAngle crosses below 0;
def BuySignal = isRising == 1 and trendAngle > 0;
def SellSignal = isFalling == 1 and trendAngle < 0;

def BuyStop = !isRising;
def SellStop = !isFalling;

###------------------------------------------------------------------------------------------
# Profit and Loss Labels
#
# Set two variables Buysignal and Sellsignal to your buy and sell signal conditions,
# or replace them below with your conditions
#
# When using large amounts of hisorical data, P/L may take time to calculate
###------------------------------------------------------------------------------------------

input showSignals = yes; #hint showSignals: show buy and sell arrows
input LongTrades = yes; #hint LongTrades: perform long trades
input ShortTrades = yes; #hint ShortTrades: perform short trades
input showLabels  = yes; #hint showLabels: show PL labels at top
input showBubbles = yes; #hint showBubbles: show PL bubbles at close of trade
input useStops = yes;     #hint useStops: use stop orders
input stopLimitDisplay = 0;  #hint stopLimit in dollars
input useAlerts = yes;    #hint useAlerts: use alerts on signals
input tradeDefinedHours = yes; #hint tradeDefinedHours:
input OpenTime = 1000; #hint OpenTime: Opening time of market
input CloseTime = 1400; #hint CloseTime: Closing time of market
input UseFuturesFees = no; #hint UseFutureFees: $6 round-trip

#Get actual trading time
def TradingHours = GetTime() between RegularTradingStart(GetYYYYMMDD()) and RegularTradingEnd(GetYYYYMMDD());

#Get time to do trading
def Begin = SecondsFromTime(OpenTime);
def End = SecondsTillTime(CloseTime);


# Only use market hours when using intraday timeframe
def isIntraDay = if GetAggregationPeriod() > 14400000 or GetAggregationPeriod() == 0 then 0 else 1;
def TradingWindow = if !tradeDefinedHours or !isIntraDay then 1 else if tradeDefinedHours and isIntraDay and Begin > 0 and End > 0 then 1 else 0;
###------------------------------------------------------------------------------------------

######################################################
##  Create Signals -
##  FILL IN THIS SECTION
##      replace 0>0 with your conditions for signals
######################################################

def PLBuySignal = if  TradingWindow and (Buysignal) then 1 else 0 ; # insert condition to create long position in place of the 0>0
def PLSellSignal =  if TradingWindow and (Sellsignal) then 1 else 0; # insert condition to create short position in place of the 0>0

def PLBuyStop  = if !useStops then 0 else if  (BuyStop) then 1 else 0  ; # insert condition to stop in place of the 0<0
def PLSellStop = if !useStops then 0 else if (SellStop) then 1 else 0  ; # insert condition to stop in place of the 0>0

def PLMktStop = if TradingWindow[-1] == 0 then 1 else 0; # If tradeDaytimeOnly is set, then stop at end of day


#######################################
##  Maintain the position of trades
#######################################

def CurrentPosition;  # holds whether flat = 0 long = 1 short = -1

if (BarNumber() == 1) or IsNaN(CurrentPosition[1]) {
    CurrentPosition = 0;
} else {
    if CurrentPosition[1] == 0 {            # FLAT
        if (PLBuySignal and LongTrades) {
            CurrentPosition = 1;
        } else if (PLSellSignal and ShortTrades) {
            CurrentPosition = -1;
        } else {
            CurrentPosition = CurrentPosition[1];
        }
    } else if CurrentPosition[1] == 1 {      # LONG
        if (PLSellSignal and ShortTrades) {
            CurrentPosition = -1;
        } else if ((PLBuyStop and useStops) or PLMktStop or (PLSellSignal and ShortTrades == 0)) {
            CurrentPosition = 0;
        } else {
            CurrentPosition = CurrentPosition[1];
        }
    } else if CurrentPosition[1] == -1 {     # SHORT
        if (PLBuySignal and LongTrades) {
            CurrentPosition = 1;
        } else if ((PLSellStop and useStops) or PLMktStop or (PLBuySignal and LongTrades == 0)) {
            CurrentPosition = 0;
        } else {
            CurrentPosition = CurrentPosition[1];
        }
    } else {
        CurrentPosition = CurrentPosition[1];
    }
}


def isLong  = if CurrentPosition == 1 then 1 else 0;
def isShort = if CurrentPosition == -1 then 1 else 0;
def isFlat  = if CurrentPosition == 0 then 1 else 0;

# If not already long and get a PLBuySignal
#Plot BuySig = if (!isLong[1] and PLBuySignal and showSignals and LongTrades) then 1 else 0;
plot BuySig = if (((isShort[1] and LongTrades) or (isFlat[1] and LongTrades)) and PLBuySignal and showSignals) then 1 else 0;
BuySig.AssignValueColor(Color.CYAN);
BuySig.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
BuySig.SetLineWeight(5);

Alert(BuySig and useAlerts, "Buy Signal", Alert.BAR, Sound.Chimes);
Alert(BuySig and useAlerts, "Buy Signal", Alert.BAR, Sound.Chimes);
Alert(BuySig and useAlerts, "Buy Signal", Alert.BAR, Sound.Chimes);
Alert(BuySig and useAlerts, "Buy Signal", Alert.BAR, Sound.Chimes);

# If not already short and get a PLSellSignal
plot SellSig = if (((isLong[1] and ShortTrades) or (isFlat[1] and ShortTrades)) and PLSellSignal and showSignals) then 1 else 0;
SellSig.AssignValueColor(Color.CYAN);
SellSig.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
SellSig.SetLineWeight(5);

Alert(SellSig and useAlerts, "Sell Signal", Alert.BAR, Sound.Chimes);
Alert(SellSig and useAlerts, "Sell Signal", Alert.BAR, Sound.Chimes);
Alert(SellSig and useAlerts, "Sell Signal", Alert.BAR, Sound.Chimes);
Alert(SellSig and useAlerts, "Sell Signal", Alert.BAR, Sound.Chimes);


# If long and get a PLBuyStop
plot BuyStpSig = if (PLBuyStop and isLong[1] and showSignals and useStops) or (isLong[1] and PLMktStop) or (isLong[1] and PLSellSignal and !ShortTrades) then 1 else 0;
BuyStpSig.AssignValueColor(Color.LIGHT_GRAY);
BuyStpSig.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
BuyStpSig.SetLineWeight(3);

Alert(BuyStpSig and useAlerts, "Buy Stop Signal", Alert.BAR, Sound.Ding);
Alert(BuyStpSig and useAlerts, "Buy Stop Signal", Alert.BAR, Sound.Ding);
Alert(BuyStpSig and useAlerts, "Buy Stop Signal", Alert.BAR, Sound.Ding);
Alert(BuyStpSig and useAlerts, "Buy Stop Signal", Alert.BAR, Sound.Ding);


# If short and get a PLSellStop
plot SellStpSig = if (PLSellStop and isShort[1] and showSignals and useStops) or (isShort[1] and PLMktStop) or (isShort[1] and PLBuySignal and !LongTrades) then 1 else 0;
SellStpSig.AssignValueColor(Color.LIGHT_GRAY);
SellStpSig.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
SellStpSig.SetLineWeight(3);

Alert(SellStpSig and useAlerts, "Sell Stop Signal", Alert.BAR, Sound.Ding);
Alert(SellStpSig and useAlerts, "Sell Stop Signal", Alert.BAR, Sound.Ding);
Alert(SellStpSig and useAlerts, "Sell Stop Signal", Alert.BAR, Sound.Ding);
Alert(SellStpSig and useAlerts, "Sell Stop Signal", Alert.BAR, Sound.Ding);


#######################################
##  Orders
#######################################

def isOrder = if ((isFlat[1] and (BuySig and LongTrades) or (SellSig and ShortTrades)) or (isLong[1] and BuyStpSig or (SellSig and ShortTrades)) or (isShort[1] and SellStpSig or (BuySig and LongTrades))) then 1 else 0 ;

def orderPrice = if (isOrder and ((BuySig and LongTrades) or (SellSig and ShortTrades))) then (if IsNaN(open[-1]) then close else open[-1]) else orderPrice[1];

plot OPL = if !isFlat and isLong then orderPrice else Double.NaN;
OPL.AssignValueColor(Color.GREEN);
OPL.SetPaintingStrategy(PaintingStrategy.LINE);
OPL.SetStyle(Curve.SHORT_DASH);
OPL.SetLineWeight(1);

#addcloud(OPL,close,color.red, color.green);

plot OPS = if !isFlat and isShort then orderPrice else Double.NaN;
OPS.AssignValueColor(Color.RED);
OPS.SetPaintingStrategy(PaintingStrategy.LINE);
OPS.SetStyle(Curve.SHORT_DASH);
OPS.SetLineWeight(1);

#addcloud(OPS,close,color.green, color.red);

def orderCount = CompoundValue(1, if IsNaN(isOrder) or BarNumber() == 1 then 0 else if (BuySig or SellSig) then orderCount[1] + 1 else orderCount[1], 0);


#######################################
##  Price and Profit
#######################################

def profitLoss;


if (!isOrder or orderPrice[1] == 0) {
    profitLoss = 0;
} else if ((isOrder and isLong[1]) and (SellSig or BuyStpSig)) {
    profitLoss = (if IsNaN(open[-1]) then close else open[-1]) - orderPrice[1];
} else if ((isOrder and isShort[1]) and (BuySig or SellStpSig)) {
    profitLoss = orderPrice[1] - (if IsNaN(open[-1]) then close else open[-1]);
} else {
    profitLoss = 0;
}


# Total Profit or Loss
def profitLossSum = CompoundValue(1, if IsNaN(isOrder)  or BarNumber() == 1 then 0 else if isOrder then profitLossSum[1] + profitLoss else profitLossSum[1], 0);

# How many trades won or lost
def profitWinners = CompoundValue(1, if IsNaN(profitWinners[1]) or BarNumber() == 1 then 0 else if isOrder and profitLoss > 0 then profitWinners[1] + 1 else profitWinners[1], 0);
def profitLosers = CompoundValue(1, if IsNaN(profitLosers[1])  or BarNumber() == 1 then 0 else if isOrder and profitLoss < 0 then profitLosers[1] + 1 else profitLosers[1], 0);
def profitPush = CompoundValue(1, if IsNaN(profitPush[1])  or BarNumber() == 1 then 0 else if isOrder and profitLoss == 0 then profitPush[1] + 1 else profitPush[1], 0);

# Current Open Trade Profit or Loss
def TradePL = if isLong then Round(((close - orderPrice) / TickSize()) * TickValue()) else if isShort then Round(((orderPrice - close) / TickSize()) * TickValue()) else 0;

# Convert to actual dollars based on Tick Value for bubbles
def dollarProfitLoss = if orderPrice[1] == 0 or IsNaN(orderPrice[1]) then 0 else Round((profitLoss / TickSize()) * TickValue());

# Closed Orders dollar P/L
def dollarPLSum = Round((profitLossSum / TickSize()) * TickValue());
def maxUpSum = CompoundValue(1, if IsNaN(maxUpSum[1]) or BarNumber() == 1 then 0 else if dollarPLSum > 0 and dollarPLSum > maxUpSum[1] then dollarPLSum else maxUpSum[1], 0);
def maxDnSum = CompoundValue(1, if IsNaN(maxDnSum[1]) or BarNumber() == 1 then 0 else if dollarPLSum < 0 and dollarPLSum < maxDnSum[1] then dollarPLSum else maxDnSum[1], 0);

# Split profits or losses by long and short trades
def profitLong = CompoundValue(1, if IsNaN(profitLong[1])  or BarNumber() == 1 then 0 else if isOrder and isLong[1] then profitLong[1] + dollarProfitLoss else profitLong[1], 0);
def profitShort = CompoundValue(1, if IsNaN(profitShort[1])  or BarNumber() == 1 then 0 else if isOrder and isShort[1] then profitShort[1] + dollarProfitLoss else profitShort[1], 0);
def countLong = CompoundValue(1, if IsNaN(countLong[1])  or BarNumber() == 1 then 0 else if isOrder and isLong[1] then countLong[1] + 1 else countLong[1], 0);
def countShort = CompoundValue(1, if IsNaN(countShort[1])  or BarNumber() == 1 then 0 else if isOrder and isShort[1] then countShort[1] + 1 else countShort[1], 0);

# What was the biggest winning and losing trade
def biggestWin = CompoundValue(1, if IsNaN(biggestWin[1]) or BarNumber() == 1 then 0 else if isOrder and (dollarProfitLoss > 0) and (dollarProfitLoss > biggestWin[1]) then dollarProfitLoss else biggestWin[1], 0);
def biggestLoss = CompoundValue(1, if IsNaN(biggestLoss[1]) or BarNumber() == 1 then 0 else if isOrder and (dollarProfitLoss < 0) and (dollarProfitLoss < biggestLoss[1]) then dollarProfitLoss else biggestLoss[1], 0);

def ClosedTradeCount = if (isLong or isShort) then orderCount - 1 else orderCount;
def OpenTrades = if (isLong or isShort) then 1 else 0;

def FuturesCommission = 8 * ClosedTradeCount;


# What percent were winners
def PCTWin = if (OpenTrades and (TradePL < 0)) then Round((profitWinners / (ClosedTradeCount + 1)) * 100, 2)
else if (OpenTrades and (TradePL > 0)) then Round(((profitWinners + 1) / (ClosedTradeCount + 1)) * 100, 2) else Round(((profitWinners) / (ClosedTradeCount)) * 100, 2) ;

# Average trade
def avgTrade = if (OpenTrades and (TradePL < 0)) then Round(((dollarPLSum - TradePL) / (ClosedTradeCount + 1)), 2)
else if (OpenTrades and (TradePL > 0)) then Round(((dollarPLSum + TradePL) / (ClosedTradeCount + 1)), 2) else Round(((dollarPLSum) / (ClosedTradeCount)), 2) ;


#######################################
##  Create Labels
#######################################


#AddLabel(showLabels and isIntraDay, if MarketOpen then "Market Open" else "Market Closed", Color.WHITE);
AddLabel(showLabels, if TradingHours then "Market Open" else "Market Closed", Color.WHITE);
AddLabel(showLabels and tradeDefinedHours, "Defined Hours", Color.WHITE);
AddLabel(showLabels and tradeDefinedHours, "Trade between: "+AsPrice(OpenTime)+" and "+AsPrice(CloseTime),Color.WHITE);
AddLabel(showLabels, GetSymbol() + " Tick Size: " + TickSize() + " Value: " + TickValue(), Color.WHITE);
AddLabel(showLabels and (LongTrades and ShortTrades), "Long+Short Trades", Color.WHITE);
AddLabel(showLabels and (LongTrades and !ShortTrades), "Long Trades Only", Color.WHITE);
AddLabel(showLabels and (!LongTrades and ShortTrades), "Short Trades Only", Color.WHITE);
AddLabel(showLabels and (UseFuturesFees), "Future Fees Incl", Color.WHITE);

AddLabel(showLabels, "Closed Orders: " + ClosedTradeCount + " P/L: " + AsDollars(dollarPLSum - if UseFuturesFees then FuturesCommission else 0), if dollarPLSum > 0 then Color.GREEN else if dollarPLSum < 0 then Color.RED else Color.GRAY);

AddLabel(if !IsNaN(orderPrice) and showLabels then 1 else 0, "Closed+Open P/L: " + AsDollars(TradePL + dollarPLSum - if UseFuturesFees then FuturesCommission else 0), if ((TradePL + dollarPLSum) > 0) then Color.GREEN else if ((TradePL + dollarPLSum - if UseFuturesFees then FuturesCommission else 0) < 0) then Color.RED else Color.GRAY);

AddLabel(showLabels, "Avg per Trade: " + AsDollars(avgTrade  - if UseFuturesFees then 6 else 0), if avgTrade > 0 then Color.GREEN else if avgTrade < 0 then Color.RED else Color.GRAY);
AddLabel(showLabels, "Winners: " + PCTWin + "%", if PCTWin > 50 then Color.GREEN else if PCTWin > 40 then Color.YELLOW else Color.GRAY);

AddLabel(showLabels, "Long Profit: " + AsDollars(profitLong), if profitLong > 0 then Color.GREEN else if profitLong < 0 then Color.RED else Color.GRAY);
AddLabel(showLabels, "Short Profit: " + AsDollars(profitShort), if profitShort > 0 then Color.GREEN else if profitShort < 0 then Color.RED else Color.GRAY);

AddLabel(showLabels, "MaxUpTrade: " + AsDollars(biggestWin) + " MaxDownTrade: " + AsDollars(biggestLoss), Color.WHITE);
AddLabel(showLabels, "MaxUpPL: " + AsDollars(maxUpSum) + " MaxDownPL: " + AsDollars(maxDnSum), Color.WHITE);

AddLabel(if !IsNaN(CurrentPosition) and showLabels and OpenTrades then 1 else 0, "Open: " + (if isLong then "Bought" else "Sold") + " @ " + orderPrice, Color.WHITE);
AddLabel(if !IsNaN(orderPrice) and showLabels and OpenTrades then 1 else 0, "Open Trade P/L: " + AsDollars(TradePL), if (TradePL > 0) then Color.GREEN else if (TradePL < 0) then Color.RED else Color.GRAY);

plot BuyStopLvl =  if isLong then OrderPrice - ((stopLimitDisplay/TickValue())*TickSize()) else double.nan;
plot ShortStopLvl =  if isShort then OrderPrice + ((stopLimitDisplay/TickValue())*TickSize()) else double.nan;
BuyStopLvl.AssignValueColor(Color.YELLOW);
BuyStopLvl.SetPaintingStrategy(PaintingStrategy.LINE);
BuyStopLvl.SetStyle(Curve.SHORT_DASH);
BuyStopLvl.SetLineWeight(1);
ShortStopLvl.AssignValueColor(Color.YELLOW);
ShortStopLvl.SetPaintingStrategy(PaintingStrategy.LINE);
ShortStopLvl.SetStyle(Curve.SHORT_DASH);
ShortStopLvl.SetLineWeight(1);

#######################################
##  Chart Bubbles for Profit/Loss
#######################################


AddChartBubble(showSignals and showBubbles and isOrder and isLong[1], low, "$" + dollarProfitLoss, if dollarProfitLoss == 0 then Color.LIGHT_GRAY else if dollarProfitLoss > 0 then Color.GREEN else Color.RED, 0);
AddChartBubble(showSignals and showBubbles and isOrder and isShort[1], high,  "$" + dollarProfitLoss, if dollarProfitLoss == 0 then Color.LIGHT_GRAY else if dollarProfitLoss > 0 then Color.GREEN else Color.RED, 1);

Full Setup
http://tos.mx/!9vSA1K


Thanks for the amazing post, JoeDV! That chart is super clean and informative love how you’ve got that lower indicator tied in. Mind sharing a few tricks behind your strategy? Do you just buy at the close of the candle when you see the arrow, assuming the lower indicator confirms? Appreciate any insights!
 
Thanks for the amazing post, JoeDV! That chart is super clean and informative love how you’ve got that lower indicator tied in. Mind sharing a few tricks behind your strategy? Do you just buy at the close of the candle when you see the arrow, assuming the lower indicator confirms? Appreciate any insights!
I always buy or sell at the open of the next bar because you don't have an actual signal until the current one is complete. (I assume that's why this is tagged as repaints) personally if an arrow shows up I considered it conditional until it's closed. granted, getting the open is not always possible so the numbers for profit and all that usually are pretty close but they're never going to be exact.

I just noticed that the up down days count thing is I believe useless and something I used prior that I think I forgot to take out. of course I'm writing from my phone so maybe I missed something but I don't see it being used anywhere.

The lower indicator is actually baked into the top so it's more just for a visual for me personally. I'm not awake 24 hours a day so I often set it to trade only between certain hours so that I'm reminded to close out positions. I would never leave a futures position open without my eyes on it, even with stops set.
 

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

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
299 Online
Create Post

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