Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Indicators to Strategy Blueprint

Based on the provided SMI Auto MTF indicator, here is the architectural blueprint for its transformation into a production-grade automated execution framework. The core logic transitions from simple crossover signals to a comprehensive system that manages entries, exits, and capital with a focus on real-world execution.

1. Execution Triggers (Entry & Direction)

The original script identifies bullish and bearish crossovers. A professional system cannot trade every crossover; it requires filters to improve signal quality and define the precise moment of execution.

2. Multi-Tiered Exit Logic

A static entry signal is insufficient for robust performance. A dynamic, multi-faceted exit strategy is required to manage risk and protect profit.

3. Capital Allocation & Risk Management

Position sizing is the most critical component for long-term viability. We will use a fixed-fractional risk model.

4. Implementation Snippet (Pine Logic)

This code block demonstrates the conversion of the indicator into a strategy incorporating the architectural principles outlined above.

//@version=5
// --- STRATEGY DECLARATION ---
strategy("SMI Execution Framework", 
     overlay=true, 
     initial_capital=100000, 
     commission_type=strategy.commission.percent, 
     commission_value=0.075, 
     slippage=2, 
     process_orders_on_close=true, // Execute on the close of the bar
     pyramiding=0) // No pyramiding allowed in this SAR model

// --- RISK MANAGEMENT INPUTS ---
i_risk_percent = input.float(1.0, "Risk Per Trade %", minval=0.1, maxval=10)
i_atr_len      = input.int(14, "ATR Period")
i_atr_stop_mult= input.float(2.0, "ATR Stop Multiplier")
i_rr_target    = input.float(1.5, "Risk/Reward Target 1")

// --- ORIGINAL SMI LOGIC (UNCHANGED) ---
i_override = input.bool(false, title="Manual Override")
i_k        = input.int(13, title="K Period (manual)",      minval=1, maxval=100)
i_smooth   = input.int(5,  title="Smooth Period (manual)", minval=1, maxval=50)
i_signal   = input.int(5,  title="Signal Period (manual)", minval=1, maxval=50)

tf = timeframe.period
auto_k = tf == "15"  ? 5  : tf == "60"  ? 9  : tf == "240" ? 13 : tf == "D"   ? 13 : tf == "W"   ? 20 : 13
auto_smooth = tf == "15"  ? 3 : tf == "60"  ? 3 : tf == "240" ? 5 : tf == "D"   ? 5 : tf == "W"   ? 7 : 5
auto_signal = tf == "15"  ? 3 : tf == "60"  ? 3 : tf == "240" ? 5 : tf == "D"   ? 5 : tf == "W"   ? 7 : 5

k_len      = i_override ? i_k      : auto_k
smooth_len = i_override ? i_smooth : auto_smooth
signal_len = i_override ? i_signal : auto_signal

hh       = ta.highest(high, k_len)
ll       = ta.lowest(low,   k_len)
mid      = (hh + ll) / 2.0
diff     = close - mid
hl_range = hh - ll
s_diff  = ta.ema(ta.ema(diff,     smooth_len), smooth_len)
s_range = ta.ema(ta.ema(hl_range, smooth_len), smooth_len)
smi    = s_range != 0.0 ? 100.0 * s_diff / (0.5 * s_range) : 0.0
sig    = ta.ema(smi, signal_len)

// --- VOLATILITY & POSITION SIZING CALCULATION ---
atr_val = ta.atr(i_atr_len)

// --- EXECUTION TRIGGERS ---
long_condition = ta.crossover(smi, sig) and smi < 0
short_condition = ta.crossunder(smi, sig) and smi > 0

// --- STRATEGY EXECUTION LOGIC ---
if strategy.position_size == 0 // Only enter if flat
    // LONG ENTRY
    if long_condition
        stop_loss_price = close - (atr_val * i_atr_stop_mult)
        risk_per_unit   = close - stop_loss_price
        take_profit_1   = close + (risk_per_unit * i_rr_target)
        
        risk_amount     = strategy.equity * (i_risk_percent / 100)
        position_size   = risk_amount / risk_per_unit

        strategy.entry("Long", strategy.long, qty=position_size)
        strategy.exit("Long TP1/SL", from_entry="Long", qty_percent=50, limit=take_profit_1, stop=stop_loss_price)
        strategy.exit("Long SL2", from_entry="Long", stop=stop_loss_price) // Stop for the remaining 50%

    // SHORT ENTRY
    if short_condition
        stop_loss_price = close + (atr_val * i_atr_stop_mult)
        risk_per_unit   = stop_loss_price - close
        take_profit_1   = close - (risk_per_unit * i_rr_target)

        risk_amount     = strategy.equity * (i_risk_percent / 100)
        position_size   = risk_amount / risk_per_unit

        strategy.entry("Short", strategy.short, qty=position_size)
        strategy.exit("Short TP1/SL", from_entry="Short", qty_percent=50, limit=take_profit_1, stop=stop_loss_price)
        strategy.exit("Short SL2", from_entry="Short", stop=stop_loss_price) // Stop for the remaining 50%

// --- STOP-AND-REVERSE LOGIC ---
if strategy.position_size > 0 and short_condition // If long and a short signal appears
    strategy.close("Long", comment="Reversal to Short")

if strategy.position_size < 0 and long_condition // If short and a long signal appears
    strategy.close("Short", comment="Reversal to Long")

// --- PLOT STOPS FOR VISUALIZATION ---
plot(strategy.position_size > 0 ? strategy.opentrades.entry_price(0) - (atr_val * i_atr_stop_mult) : na, "SL", color.red, style=plot.style_linebr)
plot(strategy.position_size < 0 ? strategy.opentrades.entry_price(0) + (atr_val * i_atr_stop_mult) : na, "SL", color.red, style=plot.style_linebr)