Page 2 of 2

Re: Forex scalping technique inside Fibonaci zone

Posted: Wed Sep 02, 2026 3:24 pm
by PTScalper
TradingView Specifics to Know:

Spread Backtesting limitations: TradingView historical data does not contain bid/ask spread history natively. Therefore, the Max Spread Filter logic will dynamically check the real-time spread via syminfo.ask and syminfo.bid while running live/forward-testing, but will bypass it during historical backtesting.

MFI Cross Array offset: In Pine Script, mfi[1] refers to the previous bar's closing MFI value, and mfi (or mfi[0]) refers to the currently forming bar's value.

Session Filtering Setup: Make sure you set the Session Filter input accurately to your targeted forex exchange times (e.g., London overlap), taking the chart's currently selected Time Zone setting into account.

Re: Forex scalping technique inside Fibonaci zone

Posted: Wed Sep 02, 2026 3:26 pm
by PTScalper
To elevate this to a truly Professional/Institutional level in TradingView, we need to move beyond just entering and exiting trades. Institutional algorithms are built around context, visual verification, and strict capital preservation.

Here are the massive upgrades added to this "Pro" version:

Multi-Timeframe (MTF) Context: Institutional scalpers do not determine the trend on the 1-minute chart. The script now dynamically fetches the 200 EMA from a higher timeframe (e.g., the 15-minute or 1-hour chart) while you execute on the M1/M5.

Dynamic OTE Killzone Drawing: The script now visually draws the Impulse Leg (trendline) and the exact 61.8% - 78.6% Fibonacci OTE Box directly on your chart when a setup triggers. This allows you to visually verify the algorithm's logic.

End-of-Session Kill Switch (Flat): Holding M1 scalps outside of active sessions destroys accounts due to spread widening. The bot will now forcefully close all open positions exactly when your session ends.

Max Daily Drawdown limit: If the algorithm hits a losing streak and breaches your defined daily loss limit (e.g., -3%), it halts all trading until the next day to protect capital.

The Institutional Pine Script v5 Code

Code: Select all

//@version=5
strategy("Institutional OTE Scalper [Elite]", overlay=true, calc_on_every_tick=true, initial_capital=10000, default_qty_type=strategy.cash, commission_type=strategy.commission.cash_per_order, commission_value=3)

// --- 1. RISK & BROKER SETTINGS ---
G_RISK = "--- Risk & Capital Protection ---"
lot_type = input.string("Auto Risk %", options=["Auto Risk %", "Fixed Volume"], group=G_RISK)
risk_pct = input.float(1.0, "Risk Per Trade (%)", step=0.1, group=G_RISK)
fixed_qty = input.float(1.0, "Fixed Volume (Contracts/Lots)", group=G_RISK)
max_daily_loss = input.float(3.0, "Max Daily Drawdown (%)", step=0.5, group=G_RISK, tooltip="Stops trading for the day if equity drops this percent from daily open")
max_spread = input.float(2.0, "Max Live Spread (Pips)", group=G_RISK)

// --- 2. TRADE LOGIC & MULTI-TIMEFRAME ---
G_LOGIC = "--- Context & Volatility ---"
htf_res = input.timeframe("15", "Macro Trend Timeframe (HTF)", group=G_LOGIC)
ema_len = input.int(200, "HTF EMA Period", group=G_LOGIC)
lookback = input.int(40, "Swing Lookback", group=G_LOGIC)
mfi_len = input.int(3, "MFI Period", group=G_LOGIC)
atr_mult = input.float(1.0, "ATR Multiplier (Stop Buffer)", group=G_LOGIC)

// --- 3. TRADE MANAGEMENT (BE & TRAIL) ---
G_MGMT = "--- Trade Management ---"
use_be = input.bool(true, "Use Break Even", group=G_MGMT)
be_trigger = input.float(5.0, "BE Trigger (Pips)", group=G_MGMT)
be_lock = input.float(0.5, "BE Lock-In (Pips)", group=G_MGMT)
use_trail = input.bool(true, "Use Trailing Stop", group=G_MGMT)
trail_step = input.float(2.0, "Trail Step (Pips)", group=G_MGMT)

// --- 4. SESSION FILTERS ---
G_SESS = "--- Session & Timing ---"
session_time = input.session("0800-1655", "Active Trading Session", group=G_SESS)
kill_eod = input.bool(true, "Close all trades at Session End", group=G_SESS)
draw_zones = input.bool(true, "Draw OTE Killzones on Chart", group=G_SESS)

// --- System & Risk Variables ---
pip_size = syminfo.type == "forex" ? syminfo.mintick * 10 : syminfo.mintick
in_session = not na(time(timeframe.period, session_time))
session_end = in_session[1] and not in_session // Detects the exact bar the session ends

// Max Daily Drawdown Logic
var float day_open_equity = strategy.equity
if dayofweek != dayofweek[1]
    day_open_equity := strategy.equity
daily_dd = ((day_open_equity - strategy.equity) / day_open_equity) * 100
hit_max_dd = daily_dd >= max_daily_loss

// --- Indicators (MTF & Local) ---
htf_ema = request.security(syminfo.tickerid, htf_res, ta.ema(close, ema_len))
mfi = ta.mfi(hlc3, mfi_len)
atr = ta.atr(14)

plot(htf_ema, "HTF 200 EMA", color=color.new(color.white, 30), linewidth=2)

// --- Price Action Swing Logic ---
high_idx = ta.highestbars(high, lookback)
low_idx  = ta.lowestbars(low, lookback)

swing_high = ta.highest(high, lookback)
swing_low  = ta.lowest(low, lookback)
swing_range = swing_high - swing_low

// Convert negative index offsets to absolute positive bars ago
bars_ago_H = math.abs(high_idx)
bars_ago_L = math.abs(low_idx)

impulse_up = (bars_ago_L > bars_ago_H) 
impulse_dn = (bars_ago_H > bars_ago_L)

// Fib Zones
fib618_L = swing_high - (swing_range * 0.618)
fib786_L = swing_high - (swing_range * 0.786)
fib618_S = swing_low + (swing_range * 0.618)
fib786_S = swing_low + (swing_range * 0.786)

// --- Entry Conditions ---
long_cond = (close > htf_ema) and impulse_up and (close <= fib618_L) and (close >= fib786_L) and (mfi[1] <= 20) and (mfi > 20) and in_session and not hit_max_dd and strategy.opentrades == 0
short_cond = (close < htf_ema) and impulse_dn and (close >= fib618_S) and (close <= fib786_S) and (mfi[1] >= 80) and (mfi < 80) and in_session and not hit_max_dd and strategy.opentrades == 0

// --- Trade State Variables ---
var float sl_level = na
var float tp_level = na

// --- Execution & Visuals Engine ---
if long_cond
    sl_level := swing_low - (atr * atr_mult)
    tp_level := swing_high
    
    sl_dist = math.abs(close - sl_level)
    risk_cash = strategy.equity * (risk_pct / 100)
    qty = lot_type == "Auto Risk %" ? (risk_cash / (sl_dist * syminfo.pointvalue)) : fixed_qty
    
    strategy.entry("OTE Long", strategy.long, qty=qty)
    strategy.exit("Exit Long", "OTE Long", stop=sl_level, limit=tp_level)
    
    // Draw Setup
    if draw_zones
        line.new(x1=time[bars_ago_L], y1=swing_low, x2=time[bars_ago_H], y2=swing_high, color=color.new(color.blue, 0), width=2, xloc=xloc.bar_time)
        box.new(left=time[bars_ago_L], top=fib618_L, right=time + (time - time[1])*5, bottom=fib786_L, border_color=color.new(color.blue, 20), bgcolor=color.new(color.blue, 80), xloc=xloc.bar_time)

if short_cond
    sl_level := swing_high + (atr * atr_mult)
    tp_level := swing_low
    
    sl_dist = math.abs(sl_level - close)
    risk_cash = strategy.equity * (risk_pct / 100)
    qty = lot_type == "Auto Risk %" ? (risk_cash / (sl_dist * syminfo.pointvalue)) : fixed_qty
    
    strategy.entry("OTE Short", strategy.short, qty=qty)
    strategy.exit("Exit Short", "OTE Short", stop=sl_level, limit=tp_level)
    
    // Draw Setup
    if draw_zones
        line.new(x1=time[bars_ago_H], y1=swing_high, x2=time[bars_ago_L], y2=swing_low, color=color.new(color.red, 0), width=2, xloc=xloc.bar_time)
        box.new(left=time[bars_ago_H], top=fib618_S, right=time + (time - time[1])*5, bottom=fib786_S, border_color=color.new(color.red, 20), bgcolor=color.new(color.red, 80), xloc=xloc.bar_time)

// --- Dynamic Break Even & Trailing Stop ---
if strategy.position_size > 0 
    curr_profit_pips = (high - strategy.position_avg_price) / pip_size
    if use_be and (curr_profit_pips >= be_trigger)
        be_price = strategy.position_avg_price + (be_lock * pip_size)
        if sl_level < be_price or na(sl_level)
            sl_level := be_price
            
    if use_trail and (sl_level >= strategy.position_avg_price) 
        trail_price = close - (trail_step * pip_size)
        if trail_price > sl_level
            sl_level := trail_price
            
    strategy.exit("Exit Long", "OTE Long", stop=sl_level, limit=tp_level)

else if strategy.position_size < 0 
    curr_profit_pips = (strategy.position_avg_price - low) / pip_size
    if use_be and (curr_profit_pips >= be_trigger)
        be_price = strategy.position_avg_price - (be_lock * pip_size)
        if sl_level > be_price or na(sl_level)
            sl_level := be_price
            
    if use_trail and (sl_level <= strategy.position_avg_price) 
        trail_price = close + (trail_step * pip_size)
        if trail_price < sl_level
            sl_level := trail_price
            
    strategy.exit("Exit Short", "OTE Short", stop=sl_level, limit=tp_level)

// --- Session Kill Switch ---
if kill_eod and session_end
    strategy.close_all(comment="EOD Flat")

// --- Pro-Grade UI Dashboard ---
var table hud = table.new(position.top_left, 1, 5, bgcolor=color.new(color.black, 70), frame_color=color.gray, frame_width=1)

if barstate.islast
    table.cell(hud, 0, 0, "■ ELITE OTE SCALPER ■", text_color=color.silver, text_size=size.small, text_halign=text.align_left)
    
    live_spread = syminfo.ask and syminfo.bid ? (syminfo.ask - syminfo.bid) / pip_size : 0.0
    table.cell(hud, 0, 1, "Spread: " + str.tostring(live_spread, "#.#") + " Pips", text_color=(live_spread <= max_spread ? color.lime : color.red), text_size=size.small, text_halign=text.align_left)
    
    table.cell(hud, 0, 2, "Session: " + (in_session ? "ACTIVE" : "CLOSED"), text_color=(in_session ? color.lime : color.orange), text_size=size.small, text_halign=text.align_left)
    table.cell(hud, 0, 3, "HTF Trend (" + htf_res + "): " + (close > htf_ema ? "BULLISH" : "BEARISH"), text_color=(close > htf_ema ? color.lime : color.red), text_size=size.small, text_halign=text.align_left)
    table.cell(hud, 0, 4, "Daily DD: " + str.tostring(daily_dd, "#.##") + "% / " + str.tostring(max_daily_loss) + "%", text_color=(hit_max_dd ? color.red : color.gray), text_size=size.small, text_halign=text.align_left)
What you will see on the chart now:

1.) A straight line connecting the Swing Low to the Swing High (the impulse leg) whenever a setup occurs.

2.) A highlighted box projecting the 61.8% to 78.6% Killzone forward in time. This is invaluable because you can visually see exactly why the bot entered the trade.

3.) The Daily DD Monitor added to the HUD so you can track how close you are to your daily pain limit.

Re: Forex scalping technique inside Fibonaci zone

Posted: Wed Sep 02, 2026 3:27 pm
by PTScalper
Here is the modified Elite OTE Scalper equipped with professional Multi-Target Partial Scaling.

Key Adjustments Implemented:

Split Position Sizing: When a setup triggers, the algorithm automatically divides your total calculated quantity into two separate legs:

Target 1 (TP1): Exactly 50% of your position.

Target 2 (TP2): The remaining 50% of your position.

Dynamic 1:1 RR Scaling: TP1 is locked precisely at a 1:1 Risk-to-Reward ratio relative to your Stop Loss distance. Once hit, half the trade is closed and secured.

Breakeven Migration on TP1: The moment TP1 is achieved, the script instantly shifts the Stop Loss for the remaining 50% (TP2) to Breakeven + Lock-in Pips, turning the rest of the trade completely risk-free while it runs toward the full impulse high/low.

The Institutional Pine Script v5 Code (Partial Take-Profit Edition)

Code: Select all

//@version=5
strategy("Institutional OTE Scalper [Partial TP]", overlay=true, calc_on_every_tick=true, initial_capital=10000, default_qty_type=strategy.cash, commission_type=strategy.commission.cash_per_order, commission_value=3)

// --- 1. RISK & CAPITAL PROTECTION ---
G_RISK = "--- Risk & Capital Protection ---"
lot_type = input.string("Auto Risk %", options=["Auto Risk %", "Fixed Volume"], group=G_RISK)
risk_pct = input.float(1.0, "Risk Per Trade (%)", step=0.1, group=G_RISK)
fixed_qty = input.float(1.0, "Fixed Total Volume (Contracts/Lots)", group=G_RISK)
max_daily_loss = input.float(3.0, "Max Daily Drawdown (%)", step=0.5, group=G_RISK)
max_spread = input.float(2.0, "Max Live Spread (Pips)", group=G_RISK)

// --- 2. TRADE LOGIC & MULTI-TIMEFRAME ---
G_LOGIC = "--- Context & Volatility ---"
htf_res = input.timeframe("15", "Macro Trend Timeframe (HTF)", group=G_LOGIC)
ema_len = input.int(200, "HTF EMA Period", group=G_LOGIC)
lookback = input.int(40, "Swing Lookback", group=G_LOGIC)
mfi_len = input.int(3, "MFI Period", group=G_LOGIC)
atr_mult = input.float(1.0, "ATR Multiplier (Stop Buffer)", group=G_LOGIC)

// --- 3. TRADE MANAGEMENT & PARTIALS ---
G_MGMT = "--- Trade Management & Partials ---"
tp1_ratio = input.float(1.0, "TP1 Risk-to-Reward Ratio", group=G_MGMT, tooltip="Ratio at which to close 50% of the position")
use_be = input.bool(true, "Move SL to BE after TP1", group=G_MGMT)
be_lock = input.float(0.5, "BE Lock-In (Pips)", group=G_MGMT)
use_trail = input.bool(true, "Use Trailing Stop on Remainder", group=G_MGMT)
trail_step = input.float(2.0, "Trail Step (Pips)", group=G_MGMT)

// --- 4. SESSION & TIMING ---
G_SESS = "--- Session & Timing ---"
session_time = input.session("0800-1655", "Active Trading Session", group=G_SESS)
kill_eod = input.bool(true, "Close all trades at Session End", group=G_SESS)
draw_zones = input.bool(true, "Draw OTE Killzones on Chart", group=G_SESS)

// --- System & Risk Variables ---
pip_size = syminfo.type == "forex" ? syminfo.mintick * 10 : syminfo.mintick
in_session = not na(time(timeframe.period, session_time))
session_end = in_session[1] and not in_session 

// Max Daily Drawdown Logic
var float day_open_equity = strategy.equity
if dayofweek != dayofweek[1]
    day_open_equity := strategy.equity
daily_dd = ((day_open_equity - strategy.equity) / day_open_equity) * 100
hit_max_dd = daily_dd >= max_daily_loss

// --- Indicators ---
htf_ema = request.security(syminfo.tickerid, htf_res, ta.ema(close, ema_len))
mfi = ta.mfi(hlc3, mfi_len)
atr = ta.atr(14)

plot(htf_ema, "HTF 200 EMA", color=color.new(color.white, 30), linewidth=2)

// --- Price Action Swing Logic ---
high_idx = ta.highestbars(high, lookback)
low_idx  = ta.lowestbars(low, lookback)

swing_high = ta.highest(high, lookback)
swing_low  = ta.lowest(low, lookback)
swing_range = swing_high - swing_low

bars_ago_H = math.abs(high_idx)
bars_ago_L = math.abs(low_idx)

impulse_up = (bars_ago_L > bars_ago_H) 
impulse_dn = (bars_ago_H > bars_ago_L)

fib618_L = swing_high - (swing_range * 0.618)
fib786_L = swing_high - (swing_range * 0.786)
fib618_S = swing_low + (swing_range * 0.618)
fib786_S = swing_low + (swing_range * 0.786)

// --- Entry Conditions ---
long_cond = (close > htf_ema) and impulse_up and (close <= fib618_L) and (close >= fib786_L) and (mfi[1] <= 20) and (mfi > 20) and in_session and not hit_max_dd and strategy.opentrades == 0
short_cond = (close < htf_ema) and impulse_dn and (close >= fib618_S) and (close <= fib786_S) and (mfi[1] >= 80) and (mfi < 80) and in_session and not hit_max_dd and strategy.opentrades == 0

// --- Trade State Variables ---
var float sl_level = na
var float tp2_level = na
var float tp1_level = na
var bool tp1_hit = false

if strategy.opentrades == 0
    tp1_hit := false // Reset state when out of trades

// --- Execution & Visuals Engine ---
if long_cond
    sl_level := swing_low - (atr * atr_mult)
    tp2_level := swing_high
    
    // Calculate 1:1 RR Target for TP1
    sl_dist = math.abs(close - sl_level)
    tp1_level := close + (sl_dist * tp1_ratio)
    
    risk_cash = strategy.equity * (risk_pct / 100)
    total_qty = lot_type == "Auto Risk %" ? (risk_cash / (sl_dist * syminfo.pointvalue)) : fixed_qty
    half_qty = total_qty / 2.0
    
    // Split into 2 distinct legs for partial scaling
    strategy.entry("OTE Long 1", strategy.long, qty=half_qty)
    strategy.exit("Exit L1", "OTE Long 1", stop=sl_level, limit=tp1_level)
    
    strategy.entry("OTE Long 2", strategy.long, qty=half_qty)
    strategy.exit("Exit L2", "OTE Long 2", stop=sl_level, limit=tp2_level)
    
    if draw_zones
        line.new(x1=time[bars_ago_L], y1=swing_low, x2=time[bars_ago_H], y2=swing_high, color=color.new(color.blue, 0), width=2, xloc=xloc.bar_time)
        box.new(left=time[bars_ago_L], top=fib618_L, right=time + (time - time[1])*5, bottom=fib786_L, border_color=color.new(color.blue, 20), bgcolor=color.new(color.blue, 80), xloc=xloc.bar_time)

if short_cond
    sl_level := swing_high + (atr * atr_mult)
    tp2_level := swing_low
    
    sl_dist = math.abs(sl_level - close)
    tp1_level := close - (sl_dist * tp1_ratio)
    
    risk_cash = strategy.equity * (risk_pct / 100)
    total_qty = lot_type == "Auto Risk %" ? (risk_cash / (sl_dist * syminfo.pointvalue)) : fixed_qty
    half_qty = total_qty / 2.0
    
    strategy.entry("OTE Short 1", strategy.short, qty=half_qty)
    strategy.exit("Exit S1", "OTE Short 1", stop=sl_level, limit=tp1_level)
    
    strategy.entry("OTE Short 2", strategy.short, qty=half_qty)
    strategy.exit("Exit S2", "OTE Short 2", stop=sl_level, limit=tp2_level)
    
    if draw_zones
        line.new(x1=time[bars_ago_H], y1=swing_high, x2=time[bars_ago_L], y2=swing_low, color=color.new(color.red, 0), width=2, xloc=xloc.bar_time)
        box.new(left=time[bars_ago_H], top=fib618_S, right=time + (time - time[1])*5, bottom=fib786_S, border_color=color.new(color.red, 20), bgcolor=color.new(color.red, 80), xloc=xloc.bar_time)

// --- Dynamic Trailing & Breakeven for Leg 2 (Remainder) ---
// If Leg 1 has closed (meaning we have 1 trade ID remaining instead of 2), trigger BE on Leg 2
if strategy.opentrades == 1 and not tp1_hit
    tp1_hit := true

if strategy.position_size > 0 and tp1_hit
    if use_be
        be_price = strategy.position_avg_price + (be_lock * pip_size)
        if sl_level < be_price
            sl_level := be_price
            
    if use_trail 
        trail_price = close - (trail_step * pip_size)
        if trail_price > sl_level
            sl_level := trail_price
            
    strategy.exit("Exit L2", "OTE Long 2", stop=sl_level, limit=tp2_level)

else if strategy.position_size < 0 and tp1_hit
    if use_be
        be_price = strategy.position_avg_price - (be_lock * pip_size)
        if sl_level > be_price
            sl_level := be_price
            
    if use_trail 
        trail_price = close + (trail_step * pip_size)
        if trail_price < sl_level
            sl_level := trail_price
            
    strategy.exit("Exit S2", "OTE Short 2", stop=sl_level, limit=tp2_level)

// --- Session Kill Switch ---
if kill_eod and session_end
    strategy.close_all(comment="EOD Flat")

// --- Pro-Grade UI Dashboard ---
var table hud = table.new(position.top_left, 1, 5, bgcolor=color.new(color.black, 70), frame_color=color.gray, frame_width=1)

if barstate.islast
    table.cell(hud, 0, 0, "■ ELITE OTE SCALPER (PARTIAL TP) ■", text_color=color.silver, text_size=size.small, text_halign=text.align_left)
    
    live_spread = syminfo.ask and syminfo.bid ? (syminfo.ask - syminfo.bid) / pip_size : 0.0
    table.cell(hud, 0, 1, "Spread: " + str.tostring(live_spread, "#.#") + " Pips", text_color=(live_spread <= max_spread ? color.lime : color.red), text_size=size.small, text_halign=text.align_left)
    
    table.cell(hud, 0, 2, "Session: " + (in_session ? "ACTIVE" : "CLOSED"), text_color=(in_session ? color.lime : color.orange), text_size=size.small, text_halign=text.align_left)
    table.cell(hud, 0, 3, "HTF Trend (" + htf_res + "): " + (close > htf_ema ? "BULLISH" : "BEARISH"), text_color=(close > htf_ema ? color.lime : color.red), text_size=size.small, text_halign=text.align_left)
    table.cell(hud, 0, 4, "Daily DD: " + str.tostring(daily_dd, "#.##") + "% / " + str.tostring(max_daily_loss) + "%", text_color=(hit_max_dd ? color.red : color.gray), text_size=size.small, text_halign=text.align_left)