Yesterdays High Breakout Trend Following Strategy
This strategy operates based on the previous trading day's high, working in a trend-following mode. It goes long when yesterday's high is broken out, even if there are multiple breakouts in a day.
Overview
This strategy operates based on the previous trading day's high, working in a trend-following mode. It goes long when yesterday's high is broken out, even if there are multiple breakouts in a day.
Strategy Logic
Use LucF function to avoid lookahead bias in backtesting.
Identify if it's a new trading day open. Record the day high max_today and low min_today.
Compare current high with max_today, update max_today if surpassed.
Compare current low with min_today, update min_today if breached.
Plot previous trading day's high and low levels.
Set entry point on breakout of previous day's high, GAP can be added to advance or delay entry.
Set stop loss percentage sl and take profit percentage tp.
Go long when price breaks previous trading day's high.
Set stop loss price and take profit price.
Optionally enable trailing stop loss, with activation level and offset distance.
Optionally close trade based on EMA crossover.
Advantage Analysis
This simple trend following strategy has the following advantages:
Clear and straightforward signal generation. Easy to implement.
Breakout of previous day's high provides trend confirmation, reducing whipsaws.
GAP parameter allows adjusting entry sensitivity.
Overall risk is controlled with clear stop loss.
Trailing stop can be used to lock in more profits.
EMA crossover avoids being trapped in downtrends.
Risk Analysis
There are some risks to note:
Failed breakout can cause losses. Reasonable stop loss needed.
Requires trending market. Whipsaws likely in ranging conditions.
Improper trailing stop can get stopped out prematurely.
Poor EMA parameter choice can make it too sensitive or lagging.
Multiple variables need tuning like GAP, stop loss, trailing stop etc.
Improvement Opportunities
Some ways to further optimize the strategy:
Use dynamic stop loss based on ATR or trend.
Add filter for valid breakout using standard deviation.
Add volatility condition to avoid false breakout in choppy markets.
Optimize EMA parameter for more robust signal.
Fine tune trailing stop parameters to match market volatility.
Test parameter robustness across different instruments.
Add dynamic position sizing mechanism.
Conclusion
The strategy is simple and practical as a typical trend following system based on previous day's high breakout. Risk management depends on stop loss primarily. With proper parameter tuning, it can perform well in trending conditions. But proper stop loss and filters are needed to avoid whipsaws. The framework can be enhanced further as a basis for trend following strategies.
Parameters
| Name | Default | What it controls |
|---|---|---|
| v_input_bool_1 | false | (?ROC Filter from CloseD)roc_enable |
| v_input_float_1 | true | Treshold |
| v_input_float_2 | true | (?Entry)Gap% |
| v_input_float_3 | 3 | Stop-loss |
| v_input_float_4 | 9 | Take-profit |
| v_input_float_5 | 2 | (?Trailing Stop Settings)Trailing-stop |
| v_input_float_6 | true | Offset Trailing |
| v_input_bool_2 | true | Trailing-stop |
| v_input_bool_3 | false | Close EMA |
| v_input_int_1 | 10 | EMA length |
Source Pine Script
/*backtest
start: 2023-09-30 00:00:00
end: 2023-10-07 00:00:00
period: 15m
basePeriod: 5m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This source code is subject to the terms of the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
// © TheSocialCryptoClub
//@version=5
strategy("Yesterday's High", overlay=true, pyramiding = 1,
initial_capital=10000,
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: https://www.tradingview.com/script/cyPWY96u-How-to-avoid-repainting-when-using-security-PineCoders-FAQ/
f_security(_sym, _res, _src, _rep) => request.security(_sym, _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 ?color.new(color.blue,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 = input.int(10, "EMA length", step=1, group = "Trailing Stop Settings")
ma1 = ta.ema(close, len1)
plot(ma1, title='EMA', color=color.new(color.yellow, 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)
else
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)
Published by ChaoZhang on the FMZ strategy square · last modified 2023-10-08. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.
Build this with AgenKit
A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Yesterdays-High-Breakout-Trend-Following-Strategy.md- npx agenkit install engineering-kit in your project
- Paste the command into your agent and approve each phase
- Get tests, backtest, risk controls and a paper-trading switch
Understand it first
Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.
Related specs
- BB Breakout StrategyPine Script · Breakout · 1d
- Donchian Channel and Larry Williams Large Trade Index StrategyPine Script · Breakout · 1m
- Dual Breakout Volatility Channel StrategyPine Script · Breakout · 1h
- Dual MA Momentum Breakout StrategyPine Script · Breakout · 1h
- Dynamic ATR Trend Following Strategy Based on Support BreakoutPine Script · Breakout · 1d
- Dynamic ATR based Trailing Stop Trading StrategyPine Script · Breakout · 1d