Repaints MTF Permission and Posture H.U.D. For ThinkOrSwim

Repaints

antwerks

Well-known member
VIP
VIP Enthusiast
PERMISSION AND POSTURE H.U.D.
This study is a lower-panel permission and posture dashboard built to help me read a setup as a living state, not as a dumb buy/sell signal. The core idea is simple: I want the lower panel to tell me whether the short-term move is fresh, mature, stretched, warning, or repair, while also showing whether the higher timeframes are actually giving permission. Instead of pretending one momentum line can solve everything, the script uses 5 minute structure for trigger context, 15 minute and 30 minute structure for permission, and VWAP plus the 9 and 21 EMAs as the backbone for trend quality. In practice, that makes it much better for real trading posture. It helps me separate a clean continuation from a damaged bounce, a tactical repair from a real reversal, and a mature trend from a no-chase condition.

XczT0Nq.jpeg


Functionally, the script is doing three jobs at once. First, it classifies the active short-term state using price location, EMA stack, EMA slope, distance from VWAP, and ATR-normalized spread between the 9 and 21 EMAs. That is what allows it to label conditions like Bull Fresh, Bull Mature, Bull Stretch, Bull Warning, and now the more honest Bull Repair or Bear Repair when price is improving but the move is still incomplete. Second, it reads the 15 minute and 30 minute timeframes as permission layers. If both are bullish, the script can justify a stronger long-bias posture. If both are bearish, it can justify a stronger short-bias posture. If they are mixed, the script knows I should usually stay tactical instead of promoting the move too early. Third, it converts all of that into an action label. That action label is the practical output. It tells me whether I should be thinking in terms of long bias, long bias no chase, tactical long only, reduce long, tactical short only, reduce short, or wait for repair.

The most important feature of the current version is the repair logic. That is what makes the study useful in damaged names like TSLA. If price is bouncing and the 5 minute structure is improving, but it is still below VWAP or the higher timeframes are still mixed, the script does not flatter the move by calling it a mature bullish trend. Instead, it labels it as Bull Repair. That matters because it keeps my expectations realistic. A repair state means the move may still be tradable, but it should be treated as tactical until the higher-timeframe reclaim is earned. The same logic works in reverse for Bear Repair, where downside structure is improving but the move has not fully earned a clean bearish continuation label.

The histogram in the lower panel is not meant to be a precise signal generator. It is there to give me a quick visual feel for posture and momentum spread. Positive values mean the 5 minute structure is acting more bullish, negative values mean it is acting more bearish, and the color intensity helps me see whether the move is fresh, mature, stretched, or just repair-quality. I should read that histogram as context, not as an instruction to click buttons. The labels do the interpretive work. The histogram just helps me feel the regime.

The way I would use this study in real time is as a permission dashboard, not as a standalone entry engine. I want the script to help me answer a few practical questions before I do anything. Is the 5 minute move actually healthy or is it just a bounce? Are the 15 minute and 30 minute backing it, or are they still mixed? Is price above or below VWAP? Is the move mature enough that I should stop chasing? Is this a spot where I should stay tactical, reduce exposure, or wait for repair? If the lower study says Bull Repair with Tactical Long Only, that tells me I can respect the bounce, but I should not mistake it for a fully healed trend. If it says Bull Mature with both 15 minute and 30 minute bullish and VWAP above, that is a much stronger continuation posture. If it says Bull Warning or Reduce Long, that tells me I should start protecting gains rather than assuming momentum is still expanding cleanly.

A good way to think about the script is that it separates state from action. The state tells me what the chart is. The action tells me how I should behave. Those are not always the same thing. For example, a chart can be in Bull Repair, which means the structure is improving, but the correct action may still be Reduce Long if the bounce is pushing into overhead resistance under mixed higher timeframes. That separation is one of the reasons this study is more useful than a generic momentum HUD. It can admit that a move is getting better without pretending that I should press aggressively.

There are a few practical ways I would interpret the main labels:

  • Bull Fresh: early constructive bullish expansion, usually one of the better spots for upside participation if permission is there.
  • Bull Mature: bullish trend is intact but no longer early, so I should be more selective and watch for no-chase behavior.
  • Bull Stretch: upside is extended, still bullish but often not a good new entry.
  • Bull Warning: bullish structure is still partly intact, but momentum is fading or price is starting to lose key support behavior.
  • Bull Repair: damaged or incomplete bullish bounce, tradable tactically but not fully healed.
  • Bear Fresh / Bear Mature / Bear Stretch / Bear Warning / Bear Repair: same logic, mirrored on the downside.
  • Reduce Long / Reduce Short: the move is not fully broken, but I should cut aggression and protect position quality.
  • Tactical Long Only / Tactical Short Only: I can still work the move, but only as a shorter-term tactical trade, not as a full-bias campaign.
  • Wait For Repair: structure is too mixed or broken to justify pressing.
The study works best when I use it together with the chart itself, not instead of the chart. I still need to care about actual price structure, reclaim shelves, prior highs and lows, and whether the move is happening into resistance or support. The dashboard is there to keep my posture honest and consistent. It is especially useful when a chart is not clearly one thing or the other, because that is where traders usually start over-labeling mediocre bounces as full reversals or overreacting to normal pullbacks as total failure. This script is trying to prevent exactly that.

If I were giving simple instructions for use, they would be these. First, use the 15 minute and 30 minute labels as permission, not the 5 minute alone. Second, treat Bull Repair and Bear Repair as tactical states until price and higher timeframes truly reclaim. Third, do not chase Bull Stretch or Bear Stretch just because the histogram is strong. Fourth, respect Reduce Long and Reduce Short as management labels, not necessarily hard reversals. Finally, let the script help me define posture, but still let actual chart structure decide triggers. That is the right relationship with this study. It is a decision aid and bias filter, not a substitute for reading the tape.
Code:
declare lower;
declare real_size;

# =========================================================
# Antwerks Permission + Posture HUD v1.1
# 5m trigger / 15m + 30m permission dashboard
#
# v1.1 patch:
# - add BULL REPAIR / BEAR REPAIR
# - tighten state precedence
# - keep dashboard/action structure intact
# =========================================================

input showDashboard = yes;
input showHistogram = yes;

input fastLen = 9;
input slowLen = 21;
input atrLen = 14;

input spreadCompression = 0.12;
input spreadFresh = 0.35;
input spreadMature = 0.75;
input spreadStretched = 1.15;

input slopeFlat = 0.02;
input losingSteamLookback = 2;
input noChaseVWAPDistanceATR = 0.90;

# -------------------------
# Core 5m context
# -------------------------
def c = close;
def h = high;
def l = low;
def o = open;

def atr = Average(TrueRange(h, c, l), atrLen);

def ema9 = ExpAverage(c, fastLen);
def ema21 = ExpAverage(c, slowLen);
def vwapVal = VWAP();

def emaBull = ema9 > ema21;
def emaBear = ema9 < ema21;

def aboveVWAP = c > vwapVal;
def belowVWAP = c < vwapVal;
def above9 = c > ema9;
def below9 = c < ema9;
def above21 = c > ema21;
def below21 = c < ema21;

def ema9SlopeRaw = (ema9 - ema9[1]) / Max(atr, TickSize());
def ema21SlopeRaw = (ema21 - ema21[1]) / Max(atr, TickSize());
def ema9Slope = Average(ema9SlopeRaw, 3);
def ema21Slope = Average(ema21SlopeRaw, 3);

def ema9Up = ema9Slope > slopeFlat;
def ema9Down = ema9Slope < -slopeFlat;
def ema9Flat = !ema9Up and !ema9Down;

def spreadATR = AbsValue(ema9 - ema21) / Max(atr, TickSize());
def pxToVWAP_ATR = (c - vwapVal) / Max(atr, TickSize());

def spreadIsCompression = spreadATR < spreadCompression;
def spreadIsFresh = spreadATR >= spreadCompression and spreadATR < spreadFresh;
def spreadIsMature = spreadATR >= spreadFresh and spreadATR < spreadMature;
def spreadIsStretched = spreadATR >= spreadMature and spreadATR < spreadStretched;
def spreadIsExtreme = spreadATR >= spreadStretched;

# -------------------------
# 15m permission
# -------------------------
def c15 = close(period = AggregationPeriod.FIFTEEN_MIN);
def ema9_15 = ExpAverage(c15, fastLen);
def ema21_15 = ExpAverage(c15, slowLen);
def atr15 = Average(TrueRange(high(period = AggregationPeriod.FIFTEEN_MIN),
                              c15,
                              low(period = AggregationPeriod.FIFTEEN_MIN)), atrLen);

def slope15 = Average((ema9_15 - ema9_15[1]) / Max(atr15, TickSize()), 3);

def bull15 = c15 > ema9_15 and ema9_15 > ema21_15 and slope15 > -slopeFlat;
def bear15 = c15 < ema9_15 and ema9_15 < ema21_15 and slope15 < slopeFlat;
def mixed15 = !bull15 and !bear15;

# -------------------------
# 30m permission
# -------------------------
def c30 = close(period = AggregationPeriod.THIRTY_MIN);
def ema9_30 = ExpAverage(c30, fastLen);
def ema21_30 = ExpAverage(c30, slowLen);
def atr30 = Average(TrueRange(high(period = AggregationPeriod.THIRTY_MIN),
                              c30,
                              low(period = AggregationPeriod.THIRTY_MIN)), atrLen);

def slope30 = Average((ema9_30 - ema9_30[1]) / Max(atr30, TickSize()), 3);

def bull30 = c30 > ema9_30 and ema9_30 > ema21_30 and slope30 > -slopeFlat;
def bear30 = c30 < ema9_30 and ema9_30 < ema21_30 and slope30 < slopeFlat;
def mixed30 = !bull30 and !bear30;

# -------------------------
# Alignment / permission
# -------------------------
def fullBullPermission = bull15 and bull30;
def fullBearPermission = bear15 and bear30;
def mixedPermission = !fullBullPermission and !fullBearPermission;

# -------------------------
# 5m trigger state
# -------------------------
def bullStructure =
    above21 and
    emaBull and
    (aboveVWAP or AbsValue(pxToVWAP_ATR) <= 0.35);

def bearStructure =
    below21 and
    emaBear and
    (belowVWAP or AbsValue(pxToVWAP_ATR) <= 0.35);

def bullFresh = bullStructure and spreadIsFresh and ema9Up;
def bullMature = bullStructure and spreadIsMature and ema9Up;
def bullStretch = bullStructure and (spreadIsStretched or spreadIsExtreme);

def bearFresh = bearStructure and spreadIsFresh and ema9Down;
def bearMature = bearStructure and spreadIsMature and ema9Down;
def bearStretch = bearStructure and (spreadIsStretched or spreadIsExtreme);

def bullMomentumCooling =
    ema9Slope <= ema9Slope[1] and
    ema9Slope[1] <= ema9Slope[2];

def bearMomentumCooling =
    ema9Slope >= ema9Slope[1] and
    ema9Slope[1] >= ema9Slope[2];

def bullWarning =
    bullStructure and
    (
        (below9 and above21 and aboveVWAP) or
        (bullMomentumCooling and above21 and aboveVWAP) or
        (belowVWAP and above21 and emaBull)
    );

def bearWarning =
    bearStructure and
    (
        (above9 and below21 and belowVWAP) or
        (bearMomentumCooling and below21 and belowVWAP) or
        (aboveVWAP and below21 and emaBear)
    );

rec bullFailureCount =
    if below21 and belowVWAP and (emaBear or ema9Down)
    then bullFailureCount[1] + 1
    else 0;

rec bearFailureCount =
    if above21 and aboveVWAP and (emaBull or ema9Up)
    then bearFailureCount[1] + 1
    else 0;

def bullFailure = bullFailureCount >= 2;
def bearFailure = bearFailureCount >= 2;

def bullRepair =
    above21 and
    emaBull and
    !bullFailure and
    !fullBullPermission and
    (
        (belowVWAP and (ema9Up or !ema9Down)) or
        (aboveVWAP and bullMomentumCooling and mixedPermission)
    );

def bearRepair =
    below21 and
    emaBear and
    !bearFailure and
    !fullBearPermission and
    (
        (aboveVWAP and (ema9Down or !ema9Up)) or
        (belowVWAP and bearMomentumCooling and mixedPermission)
    );

def bullNoChase =
    bullStretch or
    (bullMature and pxToVWAP_ATR > noChaseVWAPDistanceATR);

def bearNoChase =
    bearStretch or
    (bearMature and pxToVWAP_ATR < -noChaseVWAPDistanceATR);

# -------------------------
# NEW: Repair states
# These should override fresh/mature/stretch labels
# when short-term structure improved but context is incomplete
# -------------------------

# -------------------------
# Action logic
# -------------------------
def actionLongBias =
    fullBullPermission and bullStructure and !bullNoChase and !bullWarning and !bullFailure;

def actionLongBiasNoChase =
    fullBullPermission and bullStructure and bullNoChase and !bullFailure;

def actionAddOnReclaim =
    fullBullPermission and
    aboveVWAP and
    above9 and
    c[1] <= ema9[1] and
    !bullFailure;

def actionReduceLong =
    (fullBullPermission and bullWarning and !bullFailure) or
    (bullRepair and bullMomentumCooling and !bullFailure and !aboveVWAP);

def actionTacticalLongOnly =
    (mixedPermission and (bullStructure or bullRepair) and !bullFailure) or
    (bullRepair and !bullFailure);

def actionShortBias =
    fullBearPermission and bearStructure and !bearNoChase and !bearWarning and !bearFailure;

def actionShortBiasNoChase =
    fullBearPermission and bearStructure and bearNoChase and !bearFailure;

def actionReduceShort =
    (fullBearPermission and bearWarning and !bearFailure) or
    (bearRepair and bearMomentumCooling and !bearFailure and !belowVWAP);

def actionTacticalShortOnly =
    (mixedPermission and (bearStructure or bearRepair) and !bearFailure) or
    (bearRepair and !bearFailure);

def actionWaitForRepair =
    (!bullStructure and !bearStructure and !bullRepair and !bearRepair) or
    (mixedPermission and !actionTacticalLongOnly and !actionTacticalShortOnly and !bullFailure and !bearFailure);

def actionRiskOff =
    bullFailure or bearFailure;

# -------------------------
# Histogram
# Signed momentum posture
# -------------------------
def hist =
    if bullRepair then spreadATR * 0.75
    else if bearRepair then -spreadATR * 0.75
    else if bullStructure then spreadATR
    else if bearStructure then -spreadATR
    else 0;

plot PostureHist = if showHistogram then hist else Double.NaN;
PostureHist.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
PostureHist.SetLineWeight(4);
PostureHist.AssignValueColor(
    if bullRepair then CreateColor(120, 220, 120)
    else if bearRepair then CreateColor(220, 140, 140)
    else if bullStretch then CreateColor(120, 255, 120)
    else if bullMature then CreateColor(0, 200, 0)
    else if bullFresh then CreateColor(0, 140, 0)
    else if bearStretch then CreateColor(255, 140, 140)
    else if bearMature then CreateColor(220, 0, 0)
    else if bearFresh then CreateColor(150, 0, 0)
    else Color.GRAY
);

plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.GRAY);

# -------------------------
# Labels
# -------------------------
AddLabel(showDashboard,
    "5m STATE: " +
    (if bullFailure then "BULL FAILURE"
     else if bearFailure then "BEAR FAILURE"
     else if bullRepair then "BULL REPAIR"
     else if bearRepair then "BEAR REPAIR"
     else if bullStretch then "BULL STRETCH"
     else if bullMature then "BULL MATURE"
     else if bullFresh then "BULL FRESH"
     else if bullWarning then "BULL WARNING"
     else if bearStretch then "BEAR STRETCH"
     else if bearMature then "BEAR MATURE"
     else if bearFresh then "BEAR FRESH"
     else if bearWarning then "BEAR WARNING"
     else if spreadIsCompression then "COMPRESSION"
     else "TRANSITION"),
    if bullFailure then CreateColor(255, 80, 80)
    else if bearFailure then CreateColor(80, 220, 220)
    else if bullRepair then CreateColor(120, 220, 120)
    else if bearRepair then CreateColor(220, 140, 140)
    else if bullStretch then CreateColor(120, 255, 120)
    else if bullMature then CreateColor(0, 200, 0)
    else if bullFresh then CreateColor(0, 140, 0)
    else if bullWarning then Color.YELLOW
    else if bearStretch then CreateColor(255, 140, 140)
    else if bearMature then CreateColor(220, 0, 0)
    else if bearFresh then CreateColor(150, 0, 0)
    else if bearWarning then CreateColor(255, 160, 0)
    else Color.LIGHT_GRAY
);

AddLabel(showDashboard,
    "15m: " + (if bull15 then "BULL" else if bear15 then "BEAR" else "MIXED") +
    " | 30m: " + (if bull30 then "BULL" else if bear30 then "BEAR" else "MIXED") +
    " | VWAP: " + (if aboveVWAP then "ABOVE" else if belowVWAP then "BELOW" else "AT"),
    if fullBullPermission then CreateColor(0, 170, 0)
    else if fullBearPermission then CreateColor(170, 0, 0)
    else Color.LIGHT_GRAY
);

AddLabel(showDashboard,
    "ACTION: " +
    (if actionRiskOff then "RISK-OFF"
     else if actionReduceLong then "REDUCE LONG"
     else if actionReduceShort then "REDUCE SHORT"
     else if actionAddOnReclaim then "ADD ON RECLAIM"
     else if actionLongBiasNoChase then "LONG BIAS, NO CHASE"
     else if actionShortBiasNoChase then "SHORT BIAS, NO CHASE"
     else if actionLongBias then "LONG BIAS"
     else if actionShortBias then "SHORT BIAS"
     else if actionTacticalLongOnly then "TACTICAL LONG ONLY"
     else if actionTacticalShortOnly then "TACTICAL SHORT ONLY"
     else "WAIT FOR REPAIR"),
    if actionRiskOff then CreateColor(255, 80, 80)
    else if actionReduceLong or actionReduceShort then Color.YELLOW
    else if actionAddOnReclaim then CreateColor(0, 220, 120)
    else if actionLongBias or actionLongBiasNoChase or actionTacticalLongOnly then CreateColor(0, 170, 0)
    else if actionShortBias or actionShortBiasNoChase or actionTacticalShortOnly then CreateColor(170, 0, 0)
    else Color.GRAY
);

This dashboard is designed primarily for a 5 minute execution chart, using the 15 minute and 30 minute timeframes as permission layers. It can still be viewed on 15 minute charts for broader posture context, but it is not intended as a primary 30 minute chart study. On 30 minute charts, the logic becomes less useful because the chart timeframe itself overlaps with what the script normally treats as a higher-timeframe permission layer.
 
Last edited by a moderator:

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
1127 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top