Yesterday's High Breakout Strategy

Author: ChaoZhang, Date: 2023-11-06 10:49:57



The Yesterday’s High Breakout strategy is a trend following system that goes long when the price breaks above yesterday’s high, even if the breakout occurs multiple times in a day. It aims to follow the trending market conditions.


The strategy employs several technical indicators for entry and exit signals:

  • ROC Filter - Strategy is enabled only when today’s close has a price change percent above a threshold versus previous day’s close. This filters non-trending volatile markets.

  • Trigger Point - Records today’s high, low and open prices. Long entry triggered when price breaks above today’s high.

  • Entry and Exit Conditions - After entry, stop loss and take profit percentages are set. Trailing stop can be enabled to lock in profit. Conditional exit when price drops below a reference EMA.

  • Configuration - Gap percent to anticipate or delay entry. Customizable stop loss, take profit, trailing stop percentages.

Specifically, it tracks today’s high price for entry signal. Long entry when price breaks above today’s high. Then stop loss and take profit exits are set, with trailing stop enabled. Alternate exit when price crosses below given EMA. Optimization by setting gap percentage, adjusting stop loss and take profit ratios to control risk, enabling trailing stop to lock in profit.

Advantage Analysis

The advantages of this strategy:

  • Trend following, captures profit from trending moves.

  • Breakout strategy gives clear entry signals.

  • Considers today’s high price, avoids consecutive entries.

  • Stop loss and take profit helps risk control.

  • Trailing stop locks in profit.

  • Entry timing can be tuned with parameter optimization to control risk.

  • Simple and intuitive, easy to understand and implement.

  • Applicable for long and short trades.

Risk Analysis

The risks to consider:

  • Breakout strategies susceptible to whipsaws. Price may immediately reverse after entry.

  • Only effective for trending markets, underperforms in ranging conditions.

  • Reasonable stop loss percent needed, too wide may increase loss.

  • Reasonable gap percent needed, too aggressive may increase loss.

  • False breakout can cause unnecessary loss, tuning required.

  • Volume needs to support follow through after breakout.

  • Consistency needed between parameters across timeframes.

Optimization Directions

Possible optimizations:

  • Add other indicators like volume, volatility to avoid whipsaws during ranging markets.

  • Add curve fitting indicators to qualify trend strength, avoid false trends.

  • Dynamic optimization of entry gap based on market volatility.

  • Dynamic optimization of stop loss and take profit following market conditions.

  • Different parameter sets for different symbols and timeframes.

  • Machine learning to TEST parameter impact on strategy performance.

  • Add Options functionality to optimize configurations.

  • Research applicability during ranging market conditions.

  • Expand to cross timeframe and multi-asset strategies.


The strategy offers decent performance during trending markets based on breakout of yesterday’s high concept. But risks of whipsaw and parameter optimization difficulties exist. Further optimizations possible by adding judgments, dynamic parameter tuning, expanding to combined strategies etc. Overall it suits short term trend following, but risk control and parameter tuning needed.

start: 2023-10-06 00:00:00
end: 2023-11-05 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]

// This source code is subject to the terms of the Mozilla Public License 2.0 at
// Author: © tumiza 999 
// © TheSocialCryptoClub


strategy("Yesterday's High v.17.07", overlay=true, pyramiding = 1,
         default_qty_type=strategy.percent_of_equity, default_qty_value=10,
         slippage=1, backtest_fill_limits_assumption=1, use_bar_magnifier=true,
         commission_type=strategy.commission.percent, commission_value=0.075

// -----------------------------------------------------------------------------
// ROC Filter
// -----------------------------------------------------------------------------

// f_security function by LucF for PineCoders available here:
f_security(_sym, _res, _src, _rep) =>, _res, _src[not _rep and barstate.isrealtime ? 1 : 0])[_rep or barstate.isrealtime ? 0 : 1]
high_daily = f_security(syminfo.tickerid, "D", high, false)

roc_enable = input.bool(false, "", group="ROC Filter from CloseD", inline="roc")
roc_threshold = input.float(1, "Treshold", step=0.5, group="ROC Filter from CloseD", inline="roc")

closed = f_security(syminfo.tickerid,"1D",close, false)
roc_filter= roc_enable ? (close-closed)/closed*100  > roc_threshold  : true

// -----------------------------------------------------------------------------
// Trigger Point 
// -----------------------------------------------------------------------------

open_session = ta.change(time('D'))
price_session = ta.valuewhen(open_session, open, 0)
tf_session = timeframe.multiplier <= 60

bgcolor(open_session and tf_session ?,80):na, title = "Session")

first_bar = 0
if open_session
    first_bar := bar_index

var max_today = 0.0
var min_today = 0.0
var high_daily1 = 0.0
var low_daily1 = 0.0
var today_open = 0.0

if first_bar
    high_daily1 := max_today
    low_daily1 := min_today
    today_open := open
    max_today := high
    min_today := low

if high >= max_today
    max_today := high

if low < min_today
    min_today := low

same_day  = today_open == today_open[1]

plot( timeframe.multiplier <= 240 and same_day ? high_daily1 : na, color= color.yellow , style=plot.style_linebr, linewidth=1, title='High line')
plot( timeframe.multiplier <= 240 and same_day ? low_daily1 : na, color= #E8000D , style=plot.style_linebr, linewidth=1, title='Low line')

// -----------------------------------------------------------------------------
// Strategy settings 
// -----------------------------------------------------------------------------

Gap = input.float(1,"Gap%", step=0.5, tooltip="Gap di entrata su entry_price -n anticipa entrata, con +n posticipa entrata", group = "Entry")
Gap2 = (high_daily1 * Gap)/100

sl  = input.float(3, "Stop-loss", step= 0.5,  group = "Entry")
tp  = input.float(9, "Take-profit", step= 0.5, group = "Entry")
stop_loss_price = strategy.position_avg_price * (1-sl/100)
take_price = strategy.position_avg_price * (1+tp/100)

sl_trl = input.float(2, "Trailing-stop", step = 0.5, tooltip = "Attiva trailing stop dopo che ha raggiunto...",group = "Trailing Stop Settings")//group = "Trailing Stop Settings")
Atrl= input.float(1, "Offset Trailing", step=0.5,tooltip = "Distanza dal prezzo", group = "Trailing Stop Settings")
stop_trl_price_cond = sl_trl * high/syminfo.mintick/100
stop_trl_price_offset_cond = Atrl * high/syminfo.mintick/100

stop_tick = sl * high/syminfo.mintick/100
profit_tick = tp * high/syminfo.mintick/100

mess_buy = "buy"
mess_sell = "sell"

// -----------------------------------------------------------------------------
// Entry - Exit - Close
// -----------------------------------------------------------------------------

if close < high_daily1 and roc_filter
    strategy.entry("Entry", strategy.long, stop = high_daily1 + (Gap2), alert_message = mess_buy)

ts_n  = input.bool(true, "Trailing-stop", tooltip = "Attiva o disattiva trailing-stop", group = "Trailing Stop Settings")
close_ema = input.bool(false, "Close EMA", tooltip = "Attiva o disattiva chiusura su EMA", group = "Trailing Stop Settings")
len1 =, "EMA length", step=1, group = "Trailing Stop Settings")
ma1 = ta.ema(close, len1)

plot(ma1, title='EMA',, 0))

if ts_n == true
    strategy.exit("Trailing-Stop","Entry",loss= stop_tick, stop= stop_loss_price, limit= take_price, trail_points = stop_trl_price_cond, trail_offset = stop_trl_price_offset_cond, comment_loss="Stop-Loss!!",comment_profit ="CASH!!", comment_trailing = "TRL-Stop!!", alert_message = mess_sell)
    strategy.exit("TP-SL", "Entry",loss= stop_tick, stop=stop_loss_price, limit= take_price, comment_loss= "Stop-loss!!!", comment_profit = "CASH!!", alert_message = mess_sell)

if close_ema == true and ta.crossunder(close,ma1)
    strategy.close("Entry",comment = "Close" , alert_message = mess_sell)