jdub-price-action-strategy — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited jdub-price-action-strategy (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Skill: Jdub Price Action Strategy | Domain: trading | Category: strategy | Level: intermediate Tags:trading,strategy,price-action,jdub,direction,location,execution
Source: "Steal My Exact Price Action Strategy (Simple & Proven)" by Jdub Trades (7 years trading experience)
Three sequential steps that MUST be followed in order. Skipping any step = trading blindly.
Step 1: DIRECTION --> Step 2: LOCATION --> Step 3: EXECUTION
(Who controls?) (Where to trade?) (When to enter?)Determine the market trend on the higher timeframe before anything else.
Three market states:
| State | Structure | Action |
|---|---|---|
| Uptrend | Higher highs + higher lows | Look for longs |
| Downtrend | Lower highs + lower lows | Look for shorts |
| Consolidation | Range-bound, no clear direction | Hands off / cautious |
Rules:
Identify key Points of Interest (POIs) where risk is lowest and reward is highest.
Entry timeframe should be ~2 timeframes below the narrative/location timeframe.
| Narrative TF | Entry TF | Style |
|---|---|---|
| Weekly / Daily | Daily / 4H | Position trading, long-term |
| 4H / 1H | 1H / 15M | Swing trading, longer day trades |
| 15M | 5M / 1M | Day trading / momentum trading |
Why: Going too far apart (e.g., Daily narrative -> 1M entry = 6 TFs) causes confusion. You lose context of the higher TF thesis by the time you reach the entry TF.
The core entry model. Price must be pulling back into a key POI on the lower timeframe.
Candle 1 — Lead Candle:
Candle 2 — Reaction Candle (MOST IMPORTANT):
Candle 3 — Confirmation Candle:
| Entry | Trigger | Stop | Probability |
|---|---|---|---|
| Conservative | C3 closes bullish | Below C3 low | Highest |
| Standard | C2 closes, enter immediately | Below C2 low | Medium (no confirmation yet) |
| Aggressive | C3 breaks C2 high while forming | Below C2 low | Lower (requires strong direction + location) |
When to use aggressive entry: ONLY when Step 1 (direction) and Step 2 (location) are crystal clear. Strong HTF trend + price at key level with multiple confluences.
Same pattern inverted for short setups:
1. Check Direction (higher TF)
├── Uptrend (HH/HL) --> Look for LONGS only
├── Downtrend (LH/LL) --> Look for SHORTS only
└── Unclear/Range --> Drop 1 TF or STAY OUT
2. Mark Location (POIs on narrative TF)
├── Old highs/lows (swing structure)
├── PDH / PDL
└── Opening print / prev day close
3. Execute (entry TF, ~2 TFs below narrative)
├── Wait for price to reach POI
├── Watch three-bar pattern form
│ ├── Lead --> Reaction (buyers/sellers?) --> Confirmation
│ └── If C3 confirms --> ENTER with stop below pattern
└── If C3 fails --> NO TRADE, wait for next setupimport pandas as pd
import numpy as np
def detect_three_bar_confirmation(df: pd.DataFrame, levels: list[float],
tolerance_atr_mult: float = 0.5) -> list[dict]:
"""Detect three-bar confirmation patterns at key levels.
Args:
df: OHLCV DataFrame
levels: Key price levels (PDH, PDL, old highs/lows, etc.)
tolerance_atr_mult: How close price must be to level (in ATR multiples)
Returns:
List of detected three-bar signals with entry/stop/strength
"""
atr = (df["high"] - df["low"]).rolling(14).mean()
signals = []
for level in levels:
for i in range(2, min(20, len(df))):
idx = len(df) - i
if idx < 2:
continue
lead = df.iloc[idx - 2]
reaction = df.iloc[idx - 1]
confirm = df.iloc[idx]
tol = atr.iloc[idx] * tolerance_atr_mult
# Bullish: lead pushes down to level, reaction holds above, confirm breaks higher
if (lead["low"] <= level + tol
and lead["close"] < lead["open"]
and reaction["close"] > level
and confirm["close"] > reaction["high"]
and confirm["close"] > confirm["open"]):
strength = "STRONG" if confirm["close"] > lead["high"] else "MODERATE"
signals.append({
"type": "bullish_three_bar", "level": level, "idx": idx,
"entry": round(confirm["close"], 5),
"stop": round(min(lead["low"], reaction["low"]) - atr.iloc[idx] * 0.1, 5),
"strength": strength,
"signal": f"BUY - three-bar at {level} ({strength})"
})
# Bearish: lead pushes up to level, reaction holds below, confirm breaks lower
if (lead["high"] >= level - tol
and lead["close"] > lead["open"]
and reaction["close"] < level
and confirm["close"] < reaction["low"]
and confirm["close"] < confirm["open"]):
strength = "STRONG" if confirm["close"] < lead["low"] else "MODERATE"
signals.append({
"type": "bearish_three_bar", "level": level, "idx": idx,
"entry": round(confirm["close"], 5),
"stop": round(max(lead["high"], reaction["high"]) + atr.iloc[idx] * 0.1, 5),
"strength": strength,
"signal": f"SELL - three-bar at {level} ({strength})"
})
return signals
def get_daily_pois(df_daily: pd.DataFrame) -> dict:
"""Extract key Points of Interest from daily data.
Returns PDH, PDL, previous day close, and old swing highs/lows.
"""
if len(df_daily) < 2:
return {}
prev = df_daily.iloc[-2]
pois = {
"pdh": prev["high"],
"pdl": prev["low"],
"prev_close": prev["close"],
}
# Old swing highs/lows (last 20 sessions)
from scipy.signal import argrelextrema
recent = df_daily.tail(20)
swing_highs = argrelextrema(recent["high"].values, np.greater, order=3)[0]
swing_lows = argrelextrema(recent["low"].values, np.less, order=3)[0]
pois["old_highs"] = [round(recent["high"].iloc[h], 5) for h in swing_highs]
pois["old_lows"] = [round(recent["low"].iloc[l], 5) for l in swing_lows]
return poisSource: "The Best 9:30 AM 5 Minute Scalping Strategy (Simple & Proven)" by Jdub Trades
Same DLE framework applied to the NY open window only.
Mark these levels BEFORE the open — no marking during live price action:
def gap_fill_bias(open_930: float, prev_close: float, atr_daily: float) -> dict:
gap = open_930 - prev_close
gap_pct_atr = abs(gap) / atr_daily
return {
"gap_present": gap_pct_atr > 0.1,
"gap_direction": "UP" if gap > 0 else "DOWN",
"fill_target": prev_close,
"bias": "Expect price to fill toward prev_close FIRST before trending",
"note": "Only trade WITH trend after gap fill completes",
}1. H1/D1 trend direction confirmed? Y/N
2. PDH, PDL, prev_close marked? Y/N
3. Opening print (9:35 M5 candle) marked? Y/N
4. Gap present → gap fill likely first? Y/N
5. Price at key level (POI)? Y/N
6. 3-bar confirmation forming? Y/N
7. Time before 11:00 AM EST? Y/N
→ ENTER only if all YesSource: "The Ultimate Daily Pattern Trading Strategy (How To Find Daily Bias)" — Jdub Trades
Read the previous daily candle every morning to set bias:
| Prior Day Candle | Signal |
|---|---|
| Closed bullish, above prior high | Bullish — look for continuation longs |
| Closed bearish, below prior low | Bearish — look for continuation shorts |
| Long wick rejection at resistance | Bearish — sellers showing strength |
| Long wick rejection at support | Bullish — buyers showing strength |
| Doji / indecision at key level | No bias — wait for next candle to resolve |
| Closed inside prior day range | Range-bound — trade extremes only |
Rule: No clear candle signal = no daily bias = no trade. Skip the day.
Top of range (PDH, swing high, D1 resistance) = Premium zone
Midpoint = Fair Value
Bottom of range (PDL, swing low, D1 support) = Discount zone
Bullish bias + Price in Discount → A+ long setup
Bearish bias + Price in Premium → A+ short setup| Grade | Location | Condition |
|---|---|---|
| A+ | D1 OB or D1 FVG | Fresh (first touch) + aligned with bias |
| A | PDH / PDL | Confirmed BOS in same direction |
| B | Weekly open level | General trend direction aligned |
| C | Old swing high/low | Multiple prior touches — avoid |
Weekly open rule: Price above weekly open = bullish weekly bias; below = bearish. Monday's high/low acts as reference range for the week.
1. D1 bias confirmed (bullish/bearish from prior candle + structure)
2. Price at key daily location (PDL, D1 OB, D1 FVG, weekly open)
3. Drop to H1 chart
4. Wait for H1 CHoCH in the direction of D1 bias
5. H1 displacement candle + H1 FVG formed
6. Enter at H1 FVG | Stop: below D1 location (distal line)
7. Target: next D1 level (PDH, swing high, D1 supply zone)H1 CHoCH inside a D1 zone = institutional engagement confirmed = entry trigger.
[] D1 swing structure: HH/HL (bullish) or LH/LL (bearish)?
[] Prior day candle: what did it do? (BOS, rejection, inside bar)
[] Where is price in the dealing range? (Premium / Discount / Neutral)
[] BIAS: Bullish / Bearish / No bias (wait)
[] Key levels marked: PDH, PDL, D1 OB/FVG if present
[] Price alerts set at key levels
[] At session open: price at level? → watch H1 CHoCH + 3-bar → enter
price NOT at level? → wait, do not forceOne trade per day is enough — the daily framework produces 1–3 setups per week; selectivity is the edge.
Source: "My Simple 1 Minute Scalping Strategy To Make $10,000/Month (Backtested Results)" — Jdub Trades
A no-bias, fully mechanical variant — simpler than DLE, doesn't require directional conviction.
Step 1: Mark PDH + PDL (daily TF) → these are your TARGETS
Step 2: Mark Opening Range Candle high + low (M1 or M5 at 9:30 AM EST)
Step 3: Wait for break + retest + confirmation → enter toward PDH or PDLBullish (long):
Bearish (short):
| Action | When |
|---|---|
| Entry | After confirmation candle at ORC retest |
| Stop Loss | Just beyond opposite side of ORC |
| Partial TP (50%) | At LOD/HOD (nearest swing extreme) |
| Final TP | At PDH or PDL |
import pandas as pd
import numpy as np
from datetime import time
def orc_break_retest_signal(df_m1: pd.DataFrame, pdh: float, pdl: float,
session_start: str = "09:30") -> dict:
"""Detect Opening Range Candle break & retest setup on M1 data.
Args:
df_m1: M1 OHLCV DataFrame with datetime index (EST timezone)
pdh: Previous day high
pdl: Previous day low
session_start: NY session open time (default 09:30)
Returns:
Signal dict with entry, stop, targets, or None if no setup
"""
# Find the opening range candle (first M1 candle at session open)
today = df_m1.index[-1].date()
open_time = pd.Timestamp(f"{today} {session_start}")
orc_mask = (df_m1.index >= open_time) & (df_m1.index < open_time + pd.Timedelta(minutes=1))
orc = df_m1.loc[orc_mask]
if orc.empty:
return {"signal": "NO_SETUP", "reason": "No ORC candle found"}
orc_high = orc["high"].max()
orc_low = orc["low"].min()
# Get candles after ORC
post_orc = df_m1.loc[df_m1.index > orc.index[-1]]
if len(post_orc) < 3:
return {"signal": "WAIT", "reason": "Not enough candles after ORC"}
# Check for break above ORC-H with displacement
broke_above = False
broke_below = False
break_idx = None
for i, (idx, row) in enumerate(post_orc.iterrows()):
body = abs(row["close"] - row["open"])
candle_range = row["high"] - row["low"]
is_displacement = body > candle_range * 0.6 # 60%+ body = displacement
if row["close"] > orc_high and is_displacement and not broke_above:
broke_above = True
break_idx = i
break
if row["close"] < orc_low and is_displacement and not broke_below:
broke_below = True
break_idx = i
break
if not broke_above and not broke_below:
return {"signal": "NO_SETUP", "reason": "No displacement break of ORC"}
# Look for retest after break
post_break = post_orc.iloc[break_idx + 1:]
if len(post_break) < 2:
return {"signal": "WAIT", "reason": "Waiting for retest"}
atr = (post_orc["high"] - post_orc["low"]).mean()
tol = atr * 0.3
if broke_above:
# Look for pullback to ORC-H
for i, (idx, row) in enumerate(post_break.iterrows()):
if row["low"] <= orc_high + tol:
# Check next candle for confirmation
if i + 1 < len(post_break):
confirm = post_break.iloc[i + 1]
if confirm["close"] > orc_high and confirm["close"] > confirm["open"]:
return {
"signal": "BUY",
"entry": round(confirm["close"], 5),
"stop": round(orc_low - atr * 0.1, 5),
"tp1": round(post_orc["high"].max(), 5), # HOD
"tp2": round(pdh, 5),
"orc_high": round(orc_high, 5),
"orc_low": round(orc_low, 5),
"rr_to_pdh": round((pdh - confirm["close"]) / (confirm["close"] - orc_low), 1),
}
return {"signal": "WAIT", "reason": "Retest found, waiting for confirmation"}
if broke_below:
for i, (idx, row) in enumerate(post_break.iterrows()):
if row["high"] >= orc_low - tol:
if i + 1 < len(post_break):
confirm = post_break.iloc[i + 1]
if confirm["close"] < orc_low and confirm["close"] < confirm["open"]:
return {
"signal": "SELL",
"entry": round(confirm["close"], 5),
"stop": round(orc_high + atr * 0.1, 5),
"tp1": round(post_orc["low"].min(), 5), # LOD
"tp2": round(pdl, 5),
"orc_high": round(orc_high, 5),
"orc_low": round(orc_low, 5),
"rr_to_pdl": round((confirm["close"] - pdl) / (orc_high - confirm["close"]), 1),
}
return {"signal": "WAIT", "reason": "Retest found, waiting for confirmation"}
return {"signal": "NO_SETUP", "reason": "No retest of ORC level found"}| Condition | Use ORC Break & Retest | Use DLE |
|---|---|---|
| No clear trend / bias | Yes — no bias needed | No — needs direction |
| Strong trending day | Either works | Preferred (higher conviction) |
| First 30 min of session | Yes — designed for this | Yes (9:30 AM variant) |
| Instrument | Stocks, indices, forex | Same |
| Timeframe | M1 primary | M5 primary |
| Complexity tolerance | Simple / mechanical | More nuanced |
Source: "The Easiest 1 Minute Scalping Strategy That Actually Works" — Jdub Trades (128K views)
DLE applied across three timeframes for the tightest possible entries:
D1/H1 → DIRECTION (who controls? HH/HL or LH/LL)
M5/M15 → LOCATION (which key level is price targeting?)
M1 → EXECUTION (three-bar confirmation, enter fast)M1 vs M5 strategy comparison:
| Attribute | M5 Strategy | M1 Strategy |
|---|---|---|
| Entry TF | M5 | M1 |
| Setup TF | H1/D1 | M5/M15 |
| Stop size (SPX) | 10–30 pts | 5–15 pts |
| Typical RR | 1:2 to 1:4 | 1:3 to 1:6 |
| Confirm speed | 5 min per candle | 1 min per candle |
| Best for | Beginners | Experienced / fast execution |
M1 limit order entry:
M1 time stop: Exit stalled scalp after 10–15 min (vs 20–30 min on M5).
Same rules: 11:00 AM EST hard close; gap fill first; no bias = no trade.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.