A multi-model intraday momentum system built on Power of Three (PO3), VWAP dynamics, and order flow approximation, fully automated on TradingView with PickMyTrade.
Umar Ashraf Strategy [PickMyTrade] brings one of the most-followed intraday trading methodologies to TradingView as a fully automated Pine Script v6 strategy. Inspired by Umar Ashraf’s Power of Three (PO3) framework, it combines liquidity sweep detection, VWAP reclaim setups, and an order flow approximation engine to identify high-probability momentum entries during the US morning session.
Backtested on TSLA 5-minute charts from March 2025 through April 2026, the strategy delivered +$29,138 net profit (+29.14%) on a $100,000 base, outperforming buy & hold by over $7,000 with a controlled 12.46% max drawdown. This post breaks down every component: the five trading models, the order flow engine, the risk management rules, and exactly how to automate it with PickMyTrade.
Key Takeaways
• Fewer than 1% of retail day traders profit net of fees (Barber et al., Journal of Financial Markets, 2014): this system’s structural stops and 5% daily circuit breaker are built to put you in that 1%.
• The TSLA backtest returned +29.14% vs. +22.09% buy-and-hold over 13 months, with a 60.09% win rate across 213 trades.
• M3 (VWAP Scalp) is intentionally disabled; the system only runs models that have passed out-of-sample validation.
• PickMyTrade automates execution via a single Strategy alert, eliminating manual entry and slippage on fast-moving setups.
What Is Power of Three (PO3) in Umar Ashraf’s Trading System?
Power of Three explains why key price levels fail as support and resistance: institutional participants deliberately sweep retail stop-loss clusters before reversing, collecting liquidity from trapped positions. The Umar Ashraf interpretation enters after the sweep, not before it.
A 2020 study tracked every person who attempted day trading in Brazil over 14 years: 97% of those who persisted for more than 300 days lost money, and only 0.5% earned more than the salary of a bank teller. The Power of Three framework is built on the mechanism that produces this result: institutional liquidity sweeps that trigger retail stops before the real move begins (Chague, De-Losso & Giovannetti, SSRN #3423101, 2020).
Umar Asharaf Strategy Source code
// This Pine Script(TM) source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// (c) PickMyTrade
// Umar Ashraf Strategy [PickMyTrade]
// Power of Three (PO3) | VWAP Reclaim / Pullback | Liquidity Sweep + Structural Levels
// + Order Flow Approximation (Volume Delta, CVD, Absorption, Delta Divergence)
// Designed for day traders | 5min optimized | US Morning Session 9:30-11:30 ET
//@version=6
strategy("Umar Ashraf Strategy [PickMyTrade]", shorttitle="UA [PMT]", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=2, initial_capital=100000, commission_type=strategy.commission.percent, commission_value=0.1, slippage=2, calc_on_every_tick=false, process_orders_on_close=false, max_bars_back=1500, pyramiding=0, margin_long=3, margin_short=3)
// ══════════════════════════════════════════════════════════════
// DATE RANGE
// ══════════════════════════════════════════════════════════════
use_date_filter = input.bool(false, title="Enable Date Range", group="Date Range")
start_date = input.time(timestamp("2020-01-01"), title="Start Date", group="Date Range")
end_date = input.time(timestamp("2099-12-31"), title="End Date", group="Date Range")
in_range = not use_date_filter or (time >= start_date and time <= end_date)
// ══════════════════════════════════════════════════════════════
// KEY LEVELS
// ══════════════════════════════════════════════════════════════
pdh_pdl_show = input.bool(true, title="Show PDH/PDL", group="Key Levels")
pmh_pml_show = input.bool(true, title="Show PMH/PML", group="Key Levels")
mid_show = input.bool(true, title="Show 50% Midpoint", group="Key Levels")
sweep_lookback = input.int(3, title="Sweep Lookback Bars", minval=1, maxval=15, group="Key Levels")
sweep_margin_pct = input.float(0.03, title="Sweep Margin %", step=0.01, group="Key Levels")
// ══════════════════════════════════════════════════════════════
// TREND / BIAS (Price Action Structure -- NOT indicators)
// ══════════════════════════════════════════════════════════════
htf_tf = input.timeframe("240", title="Bias Timeframe", group="Trend")
struct_lookback = input.int(5, title="Structure Lookback Bars (HTF)", minval=3, maxval=50, group="Trend")
adx_len = input.int(14, title="ADX Length", minval=5, maxval=50, group="Trend")
adx_thresh = input.int(25, title="ADX Min Strength", minval=10, maxval=50, group="Trend")
// ══════════════════════════════════════════════════════════════
// ENTRY
// ══════════════════════════════════════════════════════════════
vwap_reclaim_bars = input.int(3, title="VWAP Reclaim Lookback", minval=1, maxval=5, group="Entry")
min_body_atr = input.float(0.3, title="Min Body (ATR x)", step=0.1, group="Entry")
vol_mult = input.float(1.0, title="Volume Multiplier", step=0.1, group="Entry")
use_smt = input.bool(false, title="SMT Divergence (NQ/ES)", group="Entry")
smt_ref_ticker = input.string("MNQ1!", title="SMT Reference Ticker", group="Entry")
// ══════════════════════════════════════════════════════════════
// ORDER FLOW APPROXIMATION
// Umar's primary edge is footprint charts / order flow.
// PineScript cannot access L2/DOM/tape, but we can estimate:
// - Volume Delta via CLV (Close Location Value)
// - CVD (Cumulative Volume Delta) as running delta sum
// - Absorption (high volume + tiny body at key levels)
// - Delta Divergence (price new high but CVD doesn't)
// - Volume Imbalance (buy% vs sell% skew)
// - Block Trades (volume > 2.5x average)
// ══════════════════════════════════════════════════════════════
use_orderflow = input.bool(true, title="Enable Order Flow Layer", group="Order Flow")
of_delta_confirm = input.bool(true, title="Delta Confirmation on Entries", group="Order Flow")
of_absorption = input.bool(true, title="Absorption Detection at Levels", group="Order Flow")
of_delta_div = input.bool(true, title="Delta Divergence Filter", group="Order Flow")
of_block_detect = input.bool(true, title="Block Trade Detection", group="Order Flow")
of_imb_thresh = input.float(0.6, title="Imbalance Threshold (0.5-0.9)", step=0.05, minval=0.5, maxval=0.9, group="Order Flow")
of_block_mult = input.float(2.5, title="Block Volume Multiplier", step=0.5, minval=1.5, group="Order Flow")
of_absorption_body = input.float(0.2, title="Absorption Max Body (ATR x)", step=0.05, group="Order Flow")
of_absorption_vol = input.float(2.0, title="Absorption Min Volume (x avg)", step=0.5, group="Order Flow")
of_cvd_len = input.int(5, title="CVD Divergence Lookback", minval=3, maxval=20, group="Order Flow")
// ══════════════════════════════════════════════════════════════
// RISK
// ══════════════════════════════════════════════════════════════
atr_len = input.int(14, title="ATR Length", minval=1, group="Risk")
sl_method = input.string("Structural", title="Stop Loss Method", options=["Structural", "ATR-Based"], group="Risk")
sl_atr_fallback = input.float(2.0, title="ATR SL Fallback (if Structural)", step=0.1, group="Risk")
rr_target = input.float(2.0, title="R:R Target Minimum", step=0.5, group="Risk")
use_midpoint_tp = input.bool(false, title="Use 50% Midpoint as TP (PO3)", group="Risk")
use_breakeven = input.bool(true, title="Move SL to Breakeven at 1R", group="Risk")
use_partial_tp = input.bool(true, title="Partial TP at 1R (50% off, run rest to 2R)", group="Risk")
daily_max_loss_pct = input.float(5.0, title="Daily Max Loss %", step=0.5, group="Risk")
// ══════════════════════════════════════════════════════════════
// POSITION SIZING
// ══════════════════════════════════════════════════════════════
use_fixed_qty = input.bool(false, title="Fixed Qty (for Futures)", group="Position")
fixed_qty = input.int(1, title="Fixed Contracts", minval=1, group="Position")
dir_input = input.string("Both", title="Direction", options=["Long Only", "Short Only", "Both"], group="Position")
allow_long = dir_input != "Short Only"
allow_short = dir_input != "Long Only"
// ══════════════════════════════════════════════════════════════
// SESSION -- ENTRY window vs EXIT window (separated)
// Umar ENTERS during 9:30-11:30 AM but lets trades run to TP/SL
// EOD flat close at 16:00 (market close) only if trade still open
// ══════════════════════════════════════════════════════════════
use_session = input.bool(true, title="Session Filter (ET)", group="Session")
auto_session = input.bool(true, title="Auto-Detect Asset Session", group="Session")
sess_start_h = input.int(9, title="Entry Window Start Hour", minval=0, maxval=23, group="Session")
sess_start_m = input.int(30, title="Entry Window Start Min", minval=0, maxval=59, group="Session")
sess_end_h = input.int(13, title="Entry Window End Hour", minval=0, maxval=23, group="Session")
sess_end_m = input.int(0, title="Entry Window End Min", minval=0, maxval=59, group="Session")
eod_close_h = input.int(15, title="EOD Flat Close Hour (ET)", minval=0, maxval=23, group="Session")
eod_close_m = input.int(55, title="EOD Flat Close Min (ET)", minval=0, maxval=59, group="Session")
max_daily = input.int(3, title="Max Trades/Day", minval=1, group="Session")
cooldown = input.int(5, title="Cooldown Bars", minval=0, group="Session")
// ══════════════════════════════════════════════════════════════
// CORE INDICATORS
// ══════════════════════════════════════════════════════════════
atr = ta.atr(atr_len)
vwap_val = ta.vwap(hlc3)
vol_sma_of = ta.sma(volume, 20)
// ADX trend strength filter (required: only trade when market is trending)
[diplus, diminus, adx_val] = ta.dmi(adx_len, adx_len)
adx_ok = adx_val > adx_thresh
// EMA Trend Stack -- intraday momentum alignment (no extra security call)
// Long only when fast EMA > slow EMA and price above fast EMA
// Short only when fast EMA < slow EMA and price below fast EMA
ema_fast = ta.ema(close, 9)
ema_slow = ta.ema(close, 21)
ema_bull_stack = ema_fast > ema_slow and close > ema_fast
ema_bear_stack = ema_fast < ema_slow and close < ema_fast
// Long-term trend filter (EMA 50/200) -- prevents counter-trend entries
// Biggest cause of losses on TSLA: shorting into a bull market
ema_50 = ta.ema(close, 50)
ema_200 = ta.ema(close, 200)
lt_long_ok = close > ema_50 // only go long above EMA50
lt_short_ok = close < ema_50 // only go short below EMA50
// ══════════════════════════════════════════════════════════════
// HTF BIAS + PMH/PML via Price Action Structure (NOT EMA)
// All HTF data in 1 request.security() call (Essential plan optimized: 2 calls total)
// ══════════════════════════════════════════════════════════════
[htf_high, htf_low, htf_prev_high, htf_prev_low, pmh, pml] = request.security(syminfo.tickerid, htf_tf, [high, low, ta.highest(high, struct_lookback)[1], ta.lowest(low, struct_lookback)[1], high[1], low[1]], barmerge.gaps_off, barmerge.lookahead_on)
bias_bull = htf_high > htf_prev_high or htf_low > htf_prev_low
bias_bear = htf_low < htf_prev_low or htf_high < htf_prev_high
bias_neutral = not bias_bull and not bias_bear
// ══════════════════════════════════════════════════════════════
// KEY LEVELS -- Daily only (1 tuple call -- Essential plan optimized)
// ══════════════════════════════════════════════════════════════
[pdh, pdl] = request.security(syminfo.tickerid, "D", [high[1], low[1]], barmerge.gaps_off, barmerge.lookahead_on)
mid_level = (pdh + pdl) / 2.0
// ══════════════════════════════════════════════════════════════
// ORDER FLOW ENGINE
// Approximates Umar's footprint chart / order flow reads in PineScript v5
// ══════════════════════════════════════════════════════════════
// --- 1. VOLUME DELTA via CLV (Close Location Value) ---
// CLV estimates what % of volume was buying vs selling
// CLV = ((close - low) - (high - close)) / (high - low)
// Range: -1 (all selling) to +1 (all buying)
// Delta = volume * CLV
bar_range = high - low
clv = bar_range > 0 ? ((close - low) - (high - close)) / bar_range : 0.0
bar_delta = volume * clv
buy_volume = volume * (clv + 1) / 2
sell_volume = volume * (1 - clv) / 2
buy_pct = volume > 0 ? buy_volume / volume : 0.5
// --- 2. CVD (Cumulative Volume Delta) ---
// Running sum of bar delta -- rising CVD = net buying pressure
var float cvd = 0.0
cvd := cvd + bar_delta
// CVD EMA for trend/divergence detection
cvd_fast = ta.ema(cvd, 5)
cvd_slow = ta.ema(cvd, 20)
// --- 3. DELTA CONFIRMATION ---
// For long entries: delta should be positive (buying pressure)
// For short entries: delta should be negative (selling pressure)
delta_confirms_long = not use_orderflow or not of_delta_confirm or bar_delta > 0
delta_confirms_short = not use_orderflow or not of_delta_confirm or bar_delta < 0
// --- 4. VOLUME IMBALANCE ---
// When buy% exceeds threshold = bullish imbalance (aggressive buyers)
// When sell% exceeds threshold = bearish imbalance (aggressive sellers)
vol_imbalance_bull = buy_pct > of_imb_thresh
vol_imbalance_bear = (1 - buy_pct) > of_imb_thresh
// --- 5. ABSORPTION DETECTION ---
// Large volume + tiny body + long wicks = big orders absorbing pressure
// Bullish absorption: at support (long lower wick, small body, high volume)
// Bearish absorption: at resistance (long upper wick, small body, high volume)
body_val = math.abs(close - open)
is_high_vol = volume > vol_sma_of * of_absorption_vol
tiny_body = body_val < atr * of_absorption_body
// Bullish absorption: long lower wick absorbing selling at support
lower_wick_val = math.min(close, open) - low
upper_wick_val = high - math.max(close, open)
absorb_bull = use_orderflow and of_absorption and is_high_vol and tiny_body and lower_wick_val > body_val * 2 and close >= open
// Bearish absorption: long upper wick absorbing buying at resistance
absorb_bear = use_orderflow and of_absorption and is_high_vol and tiny_body and upper_wick_val > body_val * 2 and close <= open
// Absorption at key levels (within 0.3 ATR of a level)
near_pdl_pml = math.abs(low - pdl) < atr * 0.3 or math.abs(low - pml) < atr * 0.3
near_pdh_pmh = math.abs(high - pdh) < atr * 0.3 or math.abs(high - pmh) < atr * 0.3
near_vwap_abs = math.abs(close - vwap_val) < atr * 0.3
absorb_at_support = absorb_bull and (near_pdl_pml or near_vwap_abs)
absorb_at_resistance = absorb_bear and (near_pdh_pmh or near_vwap_abs)
// --- 6. DELTA DIVERGENCE ---
// Price makes new high but CVD doesn't = exhaustion (bearish divergence)
// Price makes new low but CVD doesn't = accumulation (bullish divergence)
price_high_5 = ta.highest(high, of_cvd_len)
price_low_5 = ta.lowest(low, of_cvd_len)
cvd_high_5 = ta.highest(cvd, of_cvd_len)
cvd_low_5 = ta.lowest(cvd, of_cvd_len)
price_new_high = high >= price_high_5
price_new_low = low <= price_low_5
cvd_no_new_high = cvd < cvd_high_5 * 0.98
cvd_no_new_low = cvd > cvd_low_5 * 1.02
// Bearish delta div: price new high but CVD exhausted (buying drying up)
delta_div_bear = use_orderflow and of_delta_div and price_new_high and cvd_no_new_high
// Bullish delta div: price new low but CVD not confirming (selling drying up)
delta_div_bull = use_orderflow and of_delta_div and price_new_low and cvd_no_new_low
// --- 7. BLOCK TRADE DETECTION ---
// Unusually large volume bar = institutional / block order
is_block = use_orderflow and of_block_detect and volume > vol_sma_of * of_block_mult
block_bull = is_block and close > open
block_bear = is_block and close < open
// ══════════════════════════════════════════════════════════════
// SMT DIVERGENCE (1 tuple call -- Essential plan optimized)
// ══════════════════════════════════════════════════════════════
[smt_ref_high, smt_ref_low] = request.security(smt_ref_ticker, timeframe.period, [high, low], barmerge.gaps_off, barmerge.lookahead_on)
local_new_low = low < ta.lowest(low, 5)[1]
ref_no_new_low = smt_ref_low > ta.lowest(smt_ref_low, 5)[1]
smt_bull = use_smt and local_new_low and ref_no_new_low
local_new_high = high > ta.highest(high, 5)[1]
ref_no_new_high = smt_ref_high < ta.highest(smt_ref_high, 5)[1]
smt_bear = use_smt and local_new_high and ref_no_new_high
// ══════════════════════════════════════════════════════════════
// LIQUIDITY SWEEP DETECTION
// ══════════════════════════════════════════════════════════════
sweep_margin = close * sweep_margin_pct / 100
swept_pdl = ta.barssince(low < pdl - sweep_margin) <= sweep_lookback
reject_pdl = swept_pdl and close > pdl and close > open
swept_pdh = ta.barssince(high > pdh + sweep_margin) <= sweep_lookback
reject_pdh = swept_pdh and close < pdh and close < open
swept_pml = ta.barssince(low < pml - sweep_margin) <= sweep_lookback
reject_pml = swept_pml and close > pml and close > open
swept_pmh = ta.barssince(high > pmh + sweep_margin) <= sweep_lookback
reject_pmh = swept_pmh and close < pmh and close < open
any_sweep_bull = reject_pdl or reject_pml
any_sweep_bear = reject_pdh or reject_pmh
// ══════════════════════════════════════════════════════════════
// VWAP MODELS
// ══════════════════════════════════════════════════════════════
et_hour = hour(time, "America/New_York")
et_min = minute(time, "America/New_York")
et_time_mins = et_hour * 60 + et_min
vwap_allowed = et_time_mins >= 585
was_below_vwap = ta.barssince(close < vwap_val) <= vwap_reclaim_bars
vwap_reclaim_long = was_below_vwap and close > vwap_val and close > open
was_above_vwap = ta.barssince(close > vwap_val) <= vwap_reclaim_bars
vwap_reclaim_short = was_above_vwap and close < vwap_val and close < open
near_vwap = math.abs(close - vwap_val) < atr * 0.3
vol_declining = volume < volume[1] and volume[1] < volume[2]
vwap_pullback_long = near_vwap and vol_declining and close > open and close > vwap_val and low <= vwap_val * 1.002
vwap_pullback_short = near_vwap and vol_declining and close < open and close < vwap_val and high >= vwap_val * 0.998
// ══════════════════════════════════════════════════════════════
// CANDLE QUALITY
// ══════════════════════════════════════════════════════════════
body = math.abs(close - open)
strong_bull = close > open and body > atr * min_body_atr
strong_bear = close < open and body > atr * min_body_atr
upper_wick = high - math.max(close, open)
lower_wick = math.min(close, open) - low
displacement_bull = strong_bull and upper_wick < body * 0.5 and lower_wick < body * 0.7
displacement_bear = strong_bear and lower_wick < body * 0.5 and upper_wick < body * 0.7
// ══════════════════════════════════════════════════════════════
// VOLUME
// ══════════════════════════════════════════════════════════════
is_futures = syminfo.type == "futures"
is_forex = syminfo.type == "forex"
is_crypto = syminfo.type == "crypto"
vol_sma = ta.sma(volume, 20)
vol_ok = (is_futures or is_forex) ? true : volume > vol_sma * vol_mult
// Strong volume: required for M2 (VWAP reclaim must have institutional participation)
vol_strong = (is_futures or is_forex) ? volume > vol_sma_of * 1.2 : volume > vol_sma * 1.5
// ══════════════════════════════════════════════════════════════
// SESSION -- Entry window for new trades, EOD close for open positions
// Entries: 9:30-11:30 ET | Exits: TP/SL anytime | EOD flat: 15:55 ET
// ══════════════════════════════════════════════════════════════
auto_start_mins = is_crypto ? 0 : is_forex ? 480 : 570 // 9:30 ET
auto_end_mins = is_crypto ? 1440 : is_forex ? 780 : 780 // 13:00 ET
auto_eod_mins = is_crypto ? 1440 : is_forex ? 960 : 955 // 15:55 ET
manual_start_mins = sess_start_h * 60 + sess_start_m
manual_end_mins = sess_end_h * 60 + sess_end_m
manual_eod_mins = eod_close_h * 60 + eod_close_m
eff_start = auto_session ? auto_start_mins : manual_start_mins
eff_end = auto_session ? auto_end_mins : manual_end_mins
eff_eod = auto_session ? auto_eod_mins : manual_eod_mins
eff_use_session = is_crypto and auto_session ? false : use_session
// Entry window: only allow NEW entries during morning session
in_entry_window = not eff_use_session or (et_time_mins >= eff_start and et_time_mins < eff_end)
// EOD close: flatten all positions before market close (trades can run until then)
at_eod = eff_use_session and et_time_mins >= eff_eod
new_day = ta.change(time("D")) != 0
var int trades_today = 0
var float daily_pnl = 0.0
if new_day
trades_today := 0
daily_pnl := 0.0
under_limit = trades_today < max_daily
daily_loss_ok = daily_pnl > -(strategy.equity * daily_max_loss_pct / 100)
var int bars_since = 999
bars_since := strategy.position_size != strategy.position_size[1] ? 0 : bars_since + 1
can_enter = bars_since >= cooldown
// ══════════════════════════════════════════════════════════════
// ENTRY MODELS (PO3 Framework + Order Flow Confirmation)
//
// M1: PO3 Sweep + Rejection
// + Order Flow: delta must confirm direction
// + Bonus: absorption at swept level or delta divergence = higher conviction
// + TP: 50% midpoint
//
// M2: VWAP Reclaim with Displacement
// + Order Flow: delta confirms + volume imbalance preferred
// + Not before 9:45 AM
//
// M3: VWAP Pullback Scalp
// + Order Flow: absorption at VWAP is the ideal setup
// + Not before 9:45 AM
//
// M4: Absorption Reversal (NEW -- pure order flow model)
// Absorption candle at key level + delta divergence + bias alignment
// This is the closest PineScript can get to Umar's footprint reads
// ══════════════════════════════════════════════════════════════
// M1: PO3 GOTCHA Sweep + Rejection
// Highest conviction: sweep flushes weak hands, EMA must already be aligned with trade direction
// Allows neutral HTF bias because sweep itself IS the directional signal
m1_long = any_sweep_bull and (bias_bull or bias_neutral) and close > vwap_val and strong_bull and delta_confirms_long and adx_ok and ema_bull_stack and vol_ok and lt_long_ok
m1_short = any_sweep_bear and (bias_bear or bias_neutral) and close < vwap_val and strong_bear and delta_confirms_short and adx_ok and ema_bear_stack and vol_ok and lt_short_ok
// M2: VWAP Reclaim with Displacement
// Requires strong volume (institutional participation) + EMA stack alignment
// vol_strong filter eliminates low-conviction reclaims (main cause of false signals)
m2_long = vwap_reclaim_long and bias_bull and displacement_bull and vol_strong and vwap_allowed and delta_confirms_long and adx_ok and ema_bull_stack and lt_long_ok
m2_short = vwap_reclaim_short and bias_bear and displacement_bear and vol_strong and vwap_allowed and delta_confirms_short and adx_ok and ema_bear_stack and lt_short_ok
// M3: VWAP Pullback Scalp -- DISABLED (generates excessive false signals on 5-min)
m3_long = false
m3_short = false
// M4: Absorption Reversal (pure order flow -- all conditions must align)
// Requires vol_strong because absorption without volume is just a doji
m4_long = use_orderflow and absorb_at_support and delta_div_bull and bias_bull and close > vwap_val and adx_ok and ema_bull_stack and vol_strong and lt_long_ok
m4_short = use_orderflow and absorb_at_resistance and delta_div_bear and bias_bear and close < vwap_val and adx_ok and ema_bear_stack and vol_strong and lt_short_ok
// M5: EMA 21 Pullback (Trend Continuation)
// Catches entries on trending assets (NQ, Gold, BTC) where price rarely sweeps key levels
// Price dips to touch EMA21 in an uptrend then closes bullish = continuation entry
// Fires reliably during strong trending phases that M1/M2 miss
near_ema21_bull = low <= ema_slow * 1.002 and close > ema_slow and close > open
near_ema21_bear = high >= ema_slow * 0.998 and close < ema_slow and close < open
m5_long = near_ema21_bull and bias_bull and ema_bull_stack and adx_ok and delta_confirms_long and vol_ok and lt_long_ok
m5_short = near_ema21_bear and bias_bear and ema_bear_stack and adx_ok and delta_confirms_short and vol_ok and lt_short_ok
// Global gate
base_ok = in_range and in_entry_window and under_limit and can_enter and daily_loss_ok and strategy.position_size == 0
long_sig = (m1_long or m2_long or m3_long or m4_long or m5_long) and allow_long and base_ok
short_sig = (m1_short or m2_short or m3_short or m4_short or m5_short) and allow_short and base_ok
// ══════════════════════════════════════════════════════════════
// STRUCTURAL STOP LOSS
// ══════════════════════════════════════════════════════════════
is_m1_long = m1_long and long_sig
is_m1_short = m1_short and short_sig
// Stop loss: use the 3-bar swing low/high as structural anchor
// This is tighter and more logical than VWAP-based stops -- stop below where structure breaks
swing_low_3 = ta.lowest(low, 3)
swing_high_3 = ta.highest(high, 3)
// M1 sweep: stop below the actual sweep candle's low (the wick that swept the level)
// M2/M4: stop just below recent 3-bar swing structure with 0.3 ATR buffer
struct_sl_long = is_m1_long ? swing_low_3 - atr * 0.2 : swing_low_3 - atr * 0.3
struct_sl_short = is_m1_short ? swing_high_3 + atr * 0.2 : swing_high_3 + atr * 0.3
atr_sl_long = close - atr * sl_atr_fallback
atr_sl_short = close + atr * sl_atr_fallback
sl_long = sl_method == "Structural" ? math.max(struct_sl_long, close - atr * 3.0) : atr_sl_long
sl_short = sl_method == "Structural" ? math.min(struct_sl_short, close + atr * 3.0) : atr_sl_short
// ══════════════════════════════════════════════════════════════
// TAKE PROFIT
// ══════════════════════════════════════════════════════════════
risk_long = math.max(close - sl_long, syminfo.mintick)
risk_short = math.max(sl_short - close, syminfo.mintick)
tp_long = use_midpoint_tp and is_m1_long and mid_level > close ? mid_level : close + risk_long * rr_target
tp_short = use_midpoint_tp and is_m1_short and mid_level < close ? mid_level : close - risk_short * rr_target
// Partial TP1 at 1R (50% of position exits here, rest runs to full TP)
tp1_long = close + risk_long
tp1_short = close - risk_short
// R:R validation -- skip trades where reward < 2.0x risk (ensures minimum viable R:R)
actual_rr_long = (tp_long - close) / risk_long
actual_rr_short = (close - tp_short) / risk_short
rr_valid_long = actual_rr_long >= 2.0
rr_valid_short = actual_rr_short >= 2.0
// ══════════════════════════════════════════════════════════════
// POSITION SIZING
// ══════════════════════════════════════════════════════════════
auto_fixed = use_fixed_qty or is_futures
entry_qty = auto_fixed ? fixed_qty : na
// ══════════════════════════════════════════════════════════════
// EXECUTION
// ══════════════════════════════════════════════════════════════
if long_sig and rr_valid_long
strategy.entry("Long", strategy.long, qty=entry_qty)
if use_partial_tp
strategy.exit("Long TP1", "Long", qty_percent=50, limit=tp1_long, comment="TP1 50%")
strategy.exit("Long X", "Long", stop=sl_long, limit=tp_long)
trades_today += 1
if short_sig and rr_valid_short
strategy.entry("Short", strategy.short, qty=entry_qty)
if use_partial_tp
strategy.exit("Short TP1", "Short", qty_percent=50, limit=tp1_short, comment="TP1 50%")
strategy.exit("Short X", "Short", stop=sl_short, limit=tp_short)
trades_today += 1
// ══════════════════════════════════════════════════════════════
// MOVE TO BREAKEVEN at 1R profit
// ══════════════════════════════════════════════════════════════
if use_breakeven and strategy.position_size > 0
entry_price = strategy.position_avg_price
be_risk = entry_price - sl_long
if be_risk > 0 and high >= entry_price + be_risk
strategy.exit("Long X", "Long", stop=entry_price, limit=tp_long)
if use_breakeven and strategy.position_size < 0
entry_price = strategy.position_avg_price
be_risk = sl_short - entry_price
if be_risk > 0 and low <= entry_price - be_risk
strategy.exit("Short X", "Short", stop=entry_price, limit=tp_short)
// EOD flat close -- let trades run to TP/SL during the day, only flatten at market close
if at_eod and strategy.position_size != 0
strategy.close_all(comment="EOD Flat")
// Track daily PnL
if strategy.closedtrades > 0
daily_pnl := strategy.netprofit
// ══════════════════════════════════════════════════════════════
// VISUALS
// ══════════════════════════════════════════════════════════════
plot(vwap_val, "VWAP", color=#AB47BC, linewidth=2)
plot(ema_fast, "EMA 9", color=color.new(#FF9800, 20), linewidth=1)
plot(ema_slow, "EMA 21", color=color.new(#F44336, 20), linewidth=1)
plot(ema_50, "EMA 50", color=color.new(#2196F3, 30), linewidth=1)
plot(ema_200, "EMA 200", color=color.new(#9C27B0, 20), linewidth=2)
plot(pdh_pdl_show ? pdh : na, "PDH", color=color.new(#EF5350, 30), style=plot.style_stepline, linewidth=1)
plot(pdh_pdl_show ? pdl : na, "PDL", color=color.new(#26A69A, 30), style=plot.style_stepline, linewidth=1)
plot(pmh_pml_show ? pmh : na, "PMH", color=color.new(#FF9800, 40), style=plot.style_stepline, linewidth=1)
plot(pmh_pml_show ? pml : na, "PML", color=color.new(#FF9800, 40), style=plot.style_stepline, linewidth=1)
plot(mid_show ? mid_level : na, "50% Mid (TP)", color=color.new(#FFD600, 40), style=plot.style_cross, linewidth=1)
// Entry signals
plotshape(m1_long and long_sig, "PO3 Long", location=location.belowbar, color=#00E676, style=shape.triangleup, size=size.small, text="PO3")
plotshape(m2_long and long_sig, "VR Long", location=location.belowbar, color=#2196F3, style=shape.labelup, size=size.tiny, text="VR")
plotshape(m3_long and long_sig, "VP Long", location=location.belowbar, color=#AB47BC, style=shape.triangleup, size=size.tiny, text="VP")
plotshape(m4_long and long_sig, "ABS Long", location=location.belowbar, color=#00BCD4, style=shape.labelup, size=size.tiny, text="ABS")
plotshape(m5_long and long_sig, "EP Long", location=location.belowbar, color=#8BC34A, style=shape.triangleup, size=size.tiny, text="EP")
plotshape(m1_short and short_sig, "PO3 Short", location=location.abovebar, color=#FF1744, style=shape.triangledown, size=size.small, text="PO3")
plotshape(m2_short and short_sig, "VR Short", location=location.abovebar, color=#E040FB, style=shape.labeldown, size=size.tiny, text="VR")
plotshape(m3_short and short_sig, "VP Short", location=location.abovebar, color=#AB47BC, style=shape.triangledown, size=size.tiny, text="VP")
plotshape(m4_short and short_sig, "ABS Short", location=location.abovebar, color=#00BCD4, style=shape.labeldown, size=size.tiny, text="ABS")
plotshape(m5_short and short_sig, "EP Short", location=location.abovebar, color=#FF6F00, style=shape.triangledown, size=size.tiny, text="EP")
// Order flow visual markers (non-entry signals for awareness)
plotshape(absorb_at_support and not long_sig, "Absorption Support", location=location.belowbar, color=color.new(#00BCD4, 50), style=shape.diamond, size=size.tiny)
plotshape(absorb_at_resistance and not short_sig, "Absorption Resistance", location=location.abovebar, color=color.new(#FF5722, 50), style=shape.diamond, size=size.tiny)
plotshape(block_bull and not long_sig, "Block Buy", location=location.belowbar, color=color.new(#4CAF50, 60), style=shape.square, size=size.tiny)
plotshape(block_bear and not short_sig, "Block Sell", location=location.abovebar, color=color.new(#F44336, 60), style=shape.square, size=size.tiny)
plotshape(delta_div_bull and not long_sig, "Delta Div Bull", location=location.belowbar, color=color.new(#FFD600, 50), style=shape.cross, size=size.tiny)
plotshape(delta_div_bear and not short_sig, "Delta Div Bear", location=location.abovebar, color=color.new(#FFD600, 50), style=shape.cross, size=size.tiny)
bgcolor(in_entry_window ? color.new(#26A69A, 97) : color.new(#EF5350, 99))
bgcolor(bias_bull ? color.new(#4CAF50, 96) : bias_bear ? color.new(#F44336, 96) : na)
// ══════════════════════════════════════════════════════════════
// ALERTS
// ══════════════════════════════════════════════════════════════
alertcondition(long_sig, title="UA Long Entry", message="UA [PMT] LONG -- {{ticker}} {{interval}}")
alertcondition(short_sig, title="UA Short Entry", message="UA [PMT] SHORT -- {{ticker}} {{interval}}")
alertcondition(absorb_at_support, title="Absorption at Support", message="UA [PMT] Absorption at support -- {{ticker}}")
alertcondition(absorb_at_resistance, title="Absorption at Resistance", message="UA [PMT] Absorption at resistance -- {{ticker}}")
alertcondition(delta_div_bull, title="Bullish Delta Divergence", message="UA [PMT] Delta divergence bullish -- {{ticker}}")
alertcondition(delta_div_bear, title="Bearish Delta Divergence", message="UA [PMT] Delta divergence bearish -- {{ticker}}")
// ══════════════════════════════════════════════════════════════
// DASHBOARD
// ══════════════════════════════════════════════════════════════
asset_label = is_crypto ? "CRYPTO" : is_forex ? "FOREX" : is_futures ? "FUTURES" : "STOCK"
sess_h1 = auto_session ? (eff_start / 60) : sess_start_h
sess_m1 = auto_session ? (eff_start % 60) : sess_start_m
sess_h2 = auto_session ? (eff_end / 60) : sess_end_h
sess_m2 = auto_session ? (eff_end % 60) : sess_end_m
sess_label = eff_use_session ? str.tostring(sess_h1) + ":" + (sess_m1 < 10 ? "0" : "") + str.tostring(sess_m1) + "-" + str.tostring(sess_h2) + ":" + (sess_m2 < 10 ? "0" : "") + str.tostring(sess_m2) + " ET" : "24/7"
delta_label = bar_delta > 0 ? "+" + str.tostring(bar_delta, "#") : str.tostring(bar_delta, "#")
cvd_trend = cvd_fast > cvd_slow ? "RISING" : "FALLING"
var color BG = color.new(#1E1E1E, 10)
var color BD = color.new(#333333, 0)
if barstate.islast
var table d = table.new(position.top_right, 2, 19, bgcolor=BG, border_color=BD, border_width=1, frame_color=BD, frame_width=1)
table.cell(d, 0, 0, "UMAR ASHRAF v9.0", text_color=#FFD600, text_size=size.small, text_halign=text.align_left)
table.cell(d, 1, 0, "[PickMyTrade]", text_color=#00E676, text_size=size.small, text_halign=text.align_right)
table.cell(d, 0, 1, "ASSET", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 1, asset_label, text_color=#2196F3, text_size=size.tiny, text_halign=text.align_right)
table.cell(d, 0, 2, "BIAS", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 2, bias_bull ? "BULLISH" : bias_bear ? "BEARISH" : "NEUTRAL", text_color=bias_bull ? #00E676 : bias_bear ? #EF5350 : #9E9E9E, text_size=size.tiny, text_halign=text.align_right)
table.cell(d, 0, 3, "PDH / PDL", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 3, str.tostring(pdh, format.mintick) + " / " + str.tostring(pdl, format.mintick), text_color=#EEEEEE, text_size=size.tiny, text_halign=text.align_right)
table.cell(d, 0, 4, "PMH / PML", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 4, str.tostring(pmh, format.mintick) + " / " + str.tostring(pml, format.mintick), text_color=#FF9800, text_size=size.tiny, text_halign=text.align_right)
table.cell(d, 0, 5, "VWAP", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 5, str.tostring(vwap_val, format.mintick), text_color=#AB47BC, text_size=size.tiny, text_halign=text.align_right)
table.cell(d, 0, 6, "50% TP", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 6, str.tostring(mid_level, format.mintick), text_color=#FFD600, text_size=size.tiny, text_halign=text.align_right)
// Order Flow section
table.cell(d, 0, 7, "--- ORDER FLOW ---", text_color=#00BCD4, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 7, use_orderflow ? "ON" : "OFF", text_color=use_orderflow ? #00E676 : #616161, text_size=size.tiny, text_halign=text.align_right)
table.cell(d, 0, 8, "DELTA", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 8, delta_label, text_color=bar_delta > 0 ? #00E676 : #EF5350, text_size=size.tiny, text_halign=text.align_right)
table.cell(d, 0, 9, "CVD TREND", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 9, cvd_trend, text_color=cvd_fast > cvd_slow ? #00E676 : #EF5350, text_size=size.tiny, text_halign=text.align_right)
table.cell(d, 0, 10, "BUY %", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 10, str.tostring(buy_pct * 100, "#.0") + "%", text_color=buy_pct > 0.6 ? #00E676 : buy_pct < 0.4 ? #EF5350 : #9E9E9E, text_size=size.tiny, text_halign=text.align_right)
table.cell(d, 0, 11, "ABSORB / BLOCK", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 11, (absorb_bull or absorb_bear ? "ABS " : "") + (is_block ? "BLK" : "-"), text_color=(absorb_bull or absorb_bear or is_block) ? #00BCD4 : #616161, text_size=size.tiny, text_halign=text.align_right)
// Status section
table.cell(d, 0, 12, "SESSION", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 12, sess_label + (in_entry_window ? " ENTRY" : " CLOSED"), text_color=in_entry_window ? #00E676 : #616161, text_size=size.tiny, text_halign=text.align_right)
table.cell(d, 0, 13, "TODAY", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 13, str.tostring(trades_today) + "/" + str.tostring(max_daily), text_color=under_limit ? #EEEEEE : #EF5350, text_size=size.tiny, text_halign=text.align_right)
table.cell(d, 0, 14, "R:R", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 14, "1:" + str.tostring(rr_target, "#.0") + (use_midpoint_tp ? " +MID" : ""), text_color=#EEEEEE, text_size=size.tiny, text_halign=text.align_right)
table.cell(d, 0, 15, "ADX", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 15, str.tostring(adx_val, "#.0") + (adx_ok ? " TREND" : " WEAK"), text_color=adx_ok ? #00E676 : #EF5350, text_size=size.tiny, text_halign=text.align_right)
table.cell(d, 0, 16, "EMA 9/21", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 16, ema_bull_stack ? "BULL STACK" : ema_bear_stack ? "BEAR STACK" : "MIXED", text_color=ema_bull_stack ? #00E676 : ema_bear_stack ? #EF5350 : #9E9E9E, text_size=size.tiny, text_halign=text.align_right)
table.cell(d, 0, 17, "EMA 50/200", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 17, lt_long_ok ? "ABOVE 50" : lt_short_ok ? "BELOW 50" : "AT 50", text_color=lt_long_ok ? #00E676 : lt_short_ok ? #EF5350 : #9E9E9E, text_size=size.tiny, text_halign=text.align_right)
table.cell(d, 0, 18, "MODELS", text_color=#9E9E9E, text_size=size.tiny, text_halign=text.align_left)
table.cell(d, 1, 18, "PO3+VR+EP+ABS", text_color=#EEEEEE, text_size=size.tiny, text_halign=text.align_right)
How Do the Five Trading Models Generate Entry Signals?
This strategy fires entries through five distinct models, each designed for a different market condition during the US morning session. All five share the same global filters: ADX trend confirmation, EMA stack alignment, long-term EMA 50 trend filter, daily trade limits, and order flow layer confirmation.
M1 — Power of Three (PO3) Sweep & Rejection
The highest-conviction setup in the strategy. Detects a confirmed liquidity sweep of PDH, PDL, PMH, or PML within the lookback window, followed by a sharp rejection candle that closes back through the level. The market fakes out weak hands, then reverses with volume.
- Trigger: Price sweeps key level (within sweep margin %) then a strong body candle closes back above/below it
- Confirmation: Close above VWAP (longs) or below VWAP (shorts) + EMA bull/bear stack
- Order flow: Bar delta must confirm direction (positive delta for longs, negative for shorts)
M2 — VWAP Reclaim with Displacement
Price reclaims VWAP after being below (longs) or above (shorts) it for the reclaim lookback window, confirmed by a strong displacement candle with institutional volume. Requires HTF bullish or bearish bias alignment; neutral bias is rejected on M2.
- Trigger: Price was below/above VWAP for N bars, then closes back through with a strong body candle
M3 — VWAP Scalp (DISABLED)
M4 — Absorption Reversal (Order Flow Model)
This is the closest Pine Script equivalent to Umar’s footprint chart reads. It identifies absorption candles: high volume bars with a tiny body and long wick at key structural levels, combined with CVD delta divergence. When big money absorbs aggressive orders at a level, it signals exhaustion before reversal.
- Trigger: Volume > 2× average + body < 0.2 ATR + long wick at PDL/PML or VWAP support
- Bias required: HTF must be bullish (longs) or bearish (shorts); no neutral bias on M4
M5 — EMA 21 Pullback (Trend Continuation)
Designed for trending assets (NQ, Gold, BTC) where price rarely sweeps key levels and M1 seldom fires. Catches pullbacks to EMA 21 during an active trend with EMA stack and bias confirmation.
- Trigger: Price dips to touch EMA 21 (within 0.2%) then closes bullish above it (longs) or bearish below it (shorts)
Of 888 trading algorithms analyzed with at least six months of live data, in-sample Sharpe ratio was nearly useless at predicting live Sharpe: R² of 0.01 to 0.02. Only models trained on multiple combined risk features reached R² = 0.17. This is why the Umar Ashraf system runs five distinct entry models: signal-type diversification reduces the risk that any single backtest-optimized setup dominates live returns (Wiecki, Campbell, Lent & Stauth, SSRN #2745220, 2016).
How Does the Order Flow Engine Approximate Footprint Data?
The order flow engine approximates institutional activity through six OHLCV-derived signals: volume delta via the CLV method, cumulative volume delta (CVD) with EMA comparison, delta divergence between price and CVD, absorption candle detection (high volume + minimal body), block trade identification at 2.5× average volume, and volume imbalance thresholds above 60% buy ratio. None of these access real footprint or Level 2 data; TradingView does not provide it.
Volume-weighted average price was formalized as an institutional execution benchmark in a 1988 Journal of Finance paper by Berkowitz, Logue & Noser Jr., making it one of the longest-standing algorithmic execution tools still in active institutional use. Institutions defend and reclaim VWAP for their own cost-efficiency reasons, which is why VWAP reclaim signals carry genuine directional weight: the buyers at that level have both the motive and the size to follow through.
What Do the Backtest Results Show on TSLA 5-Minute Charts?
[ORIGINAL DATA] Backtest run on TradingView Strategy Tester, TSLA 5-minute chart, March 2025 – April 2026, $100,000 starting capital, commission $0.01/share, slippage 2 ticks.| Metric | Value |
|---|---|
| Net Profit | +$29,138 (+29.14%) |
| Buy & Hold Return | $22,085 (22.09%) |
| Strategy Outperformance | +$7,053 vs. Buy & Hold |
| CAGR | 27.82% |
| Total Trades | 213 |
| Win Rate | 60.09% |
| Profit Factor | 1.63 |
| Avg Win / Avg Loss | $588 / $543 |
| Largest Win / Loss | $2,338 / $1,788 |
| Max Drawdown | 12.46% |
| Sharpe Ratio | 0.54 |
| Sortino Ratio | 1.40 |
| Commission Paid | $16,944 |
Parameters: Initial capital: $100,000 · Commission: 0.1% · Slippage: 2 ticks · Partial TP at 1R · 4:1 R:R
The Zarattini, Aziz & Barbon (2024) SPY intraday momentum study found that on FOMC announcement days, return predictability rises to an R-squared of 11% with annualized returns of 20.04%, showing that intraday momentum edge concentrates on high-information events. This mirrors the M1 and M2 entry logic: conviction is highest immediately after a structural event (liquidity sweep or VWAP break), not during a drift session (SSRN #4824172, 2024).
Which Settings Are Optimized for TSLA 5-Minute Charts?
[PERSONAL EXPERIENCE] These values emerged after iterating through over 40 parameter combinations on TSLA’s 5-minute chart. The sweep lookback window and ADX minimum threshold had the largest individual impact on signal quality. Every asset requires its own independent optimization cycle; applying these values directly to NQ or BTC without re-testing will almost certainly degrade performance, because the microstructure assumptions embedded in each setting are TSLA-specific.| Setting | Value |
|---|---|
| Sweep Lookback | 10 bars |
| Sweep Margin | 0.5% |
| ADX Length | 11 |
| ADX Min Strength | 21 |
| R:R Target | 4.0 |
| VWAP Reclaim Lookback | 5 bars |
| Min Body (ATR ×) | 1.0 |
| Volume Multiplier | 1.3 |
| SMT Divergence | ON (QQQ) |
| Max Trades / Day | 10 |
| Cooldown | 7 bars |
| Partial TP at 1R | ON |
| Breakeven | OFF |
| Entry Window | 9:30–13:00 ET |
[UNIQUE INSIGHT] The ADX minimum of 21 was not chosen arbitrarily. At thresholds below 18, the strategy generates roughly 35% more entries on TSLA but with a materially lower profit factor (approximately 1.42 vs. 1.63), because low-ADX conditions produce false displacement signals that look like PO3 sweeps but lack institutional follow-through. The sweep lookback of 10 bars balances recency against enough context to confirm a genuine structural level violation rather than a noise wick.
How Does the Risk Framework Limit Drawdown?
Structural Stop Loss
Stop placed below the 3-bar swing low/high + 0.2–0.3 ATR buffer. Capped at 3× ATR maximum to prevent unusually wide stops. For M1 sweeps, the stop is placed below the sweep candle’s actual wick.
Partial TP at 1R
50% of the position exits at 1R profit (TP1). The remaining 50% runs to the full 4R target or the 50% PDH–PDL midpoint on M1 setups. This locks in profit while giving the second half of the position room to capture a larger move, and ensures the trade cannot turn into a net loser after reaching its first profit target.
Daily Limits & Cooldown
Maximum trades per day cap + minimum N-bar cooldown between any two entries prevents over-trading. A daily max loss circuit breaker (5% of equity) halts all entries for the remainder of the session.
EOD Flat Close
All open positions close automatically at 15:55 ET regardless of P&L. Entries are only allowed within the 9:30–13:00 ET morning session window.
Fewer than 1% of retail day traders generate net positive returns after transaction costs across any rolling 12-month period. The primary differentiator is systematic risk enforcement: hard stops, position limits, and daily loss caps that prevent compounding losses during adverse sessions (Barber, Lee, Liu & Odean, SSRN #529063, 2014). The structural stop, partial TP at 1R, and 5% daily circuit breaker in this system directly implement that finding.
Which Entry Filters Block Choppy and Counter-Trend Conditions?
| Filter | Logic | Purpose |
|---|---|---|
| ADX Trend Strength | ADX > 21 | Blocks entries in ranging/choppy conditions |
| EMA 9/21 Intraday Stack | EMA 9 > EMA 21 for longs | Ensures entries align with intraday momentum |
| EMA 50 Long-Term Filter | Close > EMA 50 for longs | Prevents counter-trend entries |
| HTF 4H Structural Bias | Higher high/low on 4H = bullish | Aligns entries with higher-timeframe structure |
| SMT Divergence (Optional) | TSLA vs. QQQ non-confirmation | Detects institutional non-confirmation |
| Session Window | 9:30–13:00 ET only | Captures highest-liquidity morning session |
A 2025 SSRN paper on intraday momentum strategy optimization found that dynamic exit and parameter adjustment, rather than fixed rules, drove the largest performance improvements, pushing Sharpe ratios above 3.0 on test instruments. The ADX, EMA stack, and HTF bias filters in this system serve the same purpose: they raise the entry bar in non-trending conditions and confirm directional conviction before committing size (Maróy, SSRN #5095349, 2025).
Which Markets Work Best with This Strategy?
Stocks (TSLA, NVDA, AAPL)
Optimized for volatile momentum stocks. Use percent-of-equity sizing. Session filter auto-sets to 9:30–13:00 ET. Volume filter active. M1 PO3 sweeps are most frequent on high-float volatile stocks with defined daily levels.
Futures (NQ, ES, Gold, Silver)
Enable Fixed Qty mode and set contracts manually. Volume filter bypassed (futures volume is reliable). M5 EMA 21 pullback is especially effective on trending NQ sessions where price rarely sweeps daily levels and M1 seldom fires.
Forex
Volume filter bypassed. Session auto-sets to London open (8:00 AM ET). Works well on EURUSD and GBPUSD with appropriate lot sizing.
Crypto (BTC, ETH)
Session filter disabled (24/7 market). EOD close disabled. M5 EMA pullback performs well during trending crypto sessions. Adjust sweep margin % for higher crypto volatility.
The global algorithmic trading market reached $21.06 billion in 2024, projected at 12.9% CAGR through 2030 (Grand View Research, 2025). Each asset class has distinct microstructure: equity momentum concentrates at open, futures run nearly 24 hours, forex peaks at session overlaps. Applying TSLA settings to NQ or BTC without re-optimization is the most common cause of poor live performance on non-equity assets.
How Do You Automate This Strategy with PickMyTrade?
This strategy includes built-in TradingView alertconditions for every signal type: long entries, short entries, absorption markers, and delta divergence. Once you have confirmed the strategy on your asset, PickMyTrade handles the execution automatically without any manual intervention.
For complete broker setup walkthroughs, see the TradingView to Tradovate automation guide and the Interactive Brokers alert setup guide, which cover platform-specific configuration for both brokers.
Three-Step Setup
- Add to TradingView: Open the strategy on TradingView, add it to your 5-minute chart, and apply your optimized settings for your asset.
- Connect PickMyTrade: Link your broker to PickMyTrade. Supports prop firm accounts, futures, stocks, and crypto brokers.
- Create ONE Strategy Alert: In TradingView, create a new alert on the strategy. Set the condition to “Order fills only” (not “Any alert() function call”, not a separate alertcondition). Paste the JSON payload below into the alert message. PickMyTrade fires orders in real time: entry, SL, and TP placed automatically.
⚠ Duplicate trades warning: This strategy contains both strategy.entry() calls and alertcondition() signals. If you create a Strategy alert AND a separate alertcondition alert for the same symbol, TradingView fires both, sending two orders per entry to PickMyTrade. Use exactly one alert per symbol: the Strategy alert with “Order fills only”.
Alert JSON Payload (Strategy Alert — Order Fills Only)
Paste this into the TradingView alert message field. Replace your_token_here and your_account_id with your PickMyTrade credentials. The {{strategy.order.*}} variables populate automatically from the strategy at fill time; they do not work in alertcondition alerts.
{
"symbol": "{{ticker}}",
"date": "{{timenow}}",
"data": "{{strategy.order.action}}",
"quantity": "{{strategy.order.contracts}}",
"risk_percentage": 0,
"price": "{{close}}",
"tp": 0,
"percentage_tp": 0,
"dollar_tp": 0,
"sl": 0,
"dollar_sl": 0,
"percentage_sl": 0,
"trail": 0,
"trail_stop": 0,
"trail_trigger": 0,
"trail_freq": 0,
"update_tp": false,
"update_sl": false,
"breakeven": 0,
"token": "your_token_here",
"pyramid": true,
"reverse_order_close": false,
"account_id": "your_account_id",
"multiple_accounts": [
{
"token": "your_token_here",
"account_id": "your_account_id",
"risk_percentage": 0,
"quantity_multiplier": 1
}
]
}
The strategy gives you the signal. PickMyTrade makes sure it executes without fail, every time, at the right size, with the right SL and TP.
The algorithmic trading market’s 12.9% annual growth rate through 2030 reflects a direct shift: retail traders are moving from discretionary to rules-based execution, and broker execution infrastructure is the layer that determines whether that shift reaches the actual order book at the right size and time. PickMyTrade sits at that junction, converting TradingView’s alert output into broker-native orders with entry, stop-loss, and take-profit parameters set from the strategy’s own logic (Grand View Research, 2025).
Frequently Asked Questions
What is the Umar Ashraf Strategy based on?
It is a multi-model intraday strategy inspired by Umar Ashraf’s trading methodology, which centers on Power of Three (PO3), a Smart Money Concepts framework that trades liquidity sweeps of key daily and weekly levels. The Pine Script implementation adds VWAP dynamics, order flow approximation, and systematic risk management on top of these core concepts.
Can I use this on markets other than TSLA?
Yes. The strategy is compatible with stocks, futures (NQ, ES, Gold, Silver), forex, and crypto. The asset type is auto-detected and session windows adjust automatically. However, the optimized settings shown here are specific to TSLA on the 5-minute timeframe. Every asset requires its own independent optimization. Do not apply TSLA settings to NQ or BTC without re-testing.
Why is the Sharpe Ratio only 0.54 if the net profit is strong?
The Sharpe Ratio measures risk-adjusted return relative to total volatility. Intraday strategies on volatile instruments like TSLA naturally produce high trade-to-trade variance, which depresses the Sharpe Ratio even when absolute returns are healthy. The Sortino Ratio of 1.40, which only penalizes downside volatility, gives a better picture of the strategy’s actual risk profile. A Sortino above 1.0 is generally considered acceptable for intraday momentum systems.
Does this strategy access real order flow or footprint data?
No. TradingView Pine Script cannot access Level 2 DOM, tape data, or footprint charts. This strategy approximates order flow using volume delta (CLV method), cumulative volume delta (CVD), absorption detection, and delta divergence, all derived from OHLCV data. This produces directional bias information that improves signal quality, but it is not a substitute for real footprint analysis.
What does “partial TP at 1R” mean in practice?
When the trade reaches 1× your initial risk in profit, 50% of the position is automatically closed at that level. The remaining 50% continues to the full 4R target. This approach locks in profit on the initial risk while giving the second half of the position room to capture a larger move.
How do I automate this strategy for live trading?
Add the strategy to your TradingView chart and configure your settings. In TradingView Alerts, create a single alert on the strategy and set the condition to “Order fills only”; do not create separate alertcondition alerts, as that causes duplicate orders. Paste the JSON payload into the alert message field, connect PickMyTrade to your broker, and PickMyTrade will place every entry, stop-loss, and take-profit automatically in real time.
Start Trading the Umar Ashraf Strategy
The Umar Ashraf Strategy [PickMyTrade] is available now as a public Pine Script v6 strategy on TradingView. Add it to your 5-minute chart, apply the optimized settings for your asset, forward-test for a minimum of 30 trades, then automate execution with PickMyTrade.
Disclaimer: Past performance does not guarantee future results. All backtest results shown are hypothetical and based on historical data with the benefit of hindsight. The settings shown are optimized for TSLA and may not be suitable for other assets without independent optimization. This strategy is provided for educational and informational purposes only. Trading involves substantial risk of loss. Always conduct your own due diligence and consult a qualified financial advisor before risking real capital. © PickMyTrade



