Momentum Swing Trading Strategy
This is a daily interval swing trading strategy based on momentum techniques using ATR Stops. It was created by Kory Hoang from Stably. The strategy identifies trend direction using momentum indicators and sets stop…

Overview
This is a daily interval swing trading strategy based on momentum techniques using ATR Stops. It was created by Kory Hoang from Stably.
The strategy identifies trend direction using momentum indicators and sets stop loss lines based on ATR to implement low-buy-high-sell swing trading.
Strategy Logic
The code first sets the backtesting time range.
Then in the indicator section, the following indicators are calculated:
- atr(): calculate ATR for stop loss;
- max_/min_: highest/lowest price of the previous bar;
- is_uptrend: judge if it's in an uptrend;
- vstop: stop loss line;
The main logic to judge trend is:
If close is higher than the previous downside stop loss line vstop, it's judged as an uptrend; if close is lower than the previous upside stop loss line vstop, it's judged as a downtrend.
When trend changes, adjust the stop loss line position.
Specifically, in an uptrend, the stop loss line is set to the highest price of the previous bar minus the ATR value; in a downtrend, the stop loss line is set to the lowest price of the previous bar plus the ATR value.
This realizes trend following stop loss.
In the trading rules section, open long/short positions when price breaks the stop loss line.
Advantage Analysis
The advantages of this strategy:
- Judge trend direction using momentum techniques, timely catch turning points and avoid false breakouts.
- ATR stop loss traces highest/lowest price, can control risk well.
- Simple and clear strategy logic, easy to understand and implement.
- Can make low-buy-high-sell trades between swings.
Risk Analysis
There are also some risks:
- Improper ATR parameter may cause stop loss to be too loose or too tight.
- Fierce whipsaws may happen in ranging trends, causing consecutive stop loss.
- High trading frequency, higher commissions.
Some optimizations:
- Test different ATR parameters to find the optimal.
- Optimize stop loss combining volatility metrics on top of ATR.
- Add trend filter to avoid unnecessary trades during choppy markets.
Optimization Directions
Some directions to optimize this strategy:
Test different ATR parameters to find the optimal. Backtest multiple parameter sets and evaluate return/risk ratio.
Optimize stop loss combining volatility metrics on top of ATR. Add volatility metrics, relax stop loss properly during periods of increasing volatility.
Add trend filter to avoid trades during choppy market. Add trend judgment indicators, only trade when trend is clear.
Add position sizing mechanism. Adjust position size based on account utilization ratio, consecutive stop loss times etc.
Add overnight gap risk control. Actively cut loss before market close to avoid overnight gap risk.
Conclusion
As a basic daily swing trading strategy, the overall logic is clear. It judges trend with momentum techniques and utilizes ATR for trailing stop loss, effectively controlling risk.
Still large room for optimization, can improve from aspects like trend judgment, stop loss method, position sizing etc. to make the strategy more practical. Overall this strategy provides a solid framework for quantitative trading.
Parameters
| Name | Default | What it controls |
|---|---|---|
| v_input_1 | true | From Month |
| v_input_2 | true | From Day |
| v_input_3 | 2010 | From Year |
| v_input_4 | 12 | To Month |
| v_input_5 | 31 | To Day |
| v_input_6 | 2020 | To Year |
| v_input_7 | 3 | length |
| v_input_8 | true | mult |
| v_input_9 | true | Strategy Direction |
Source Pine Script
/*backtest
start: 2023-01-29 00:00:00
end: 2024-02-04 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=2
strategy("BTC Swinger", overlay=true, commission_value = 0.25, default_qty_type=strategy.percent_of_equity, default_qty_value = 100)
/////////////////////////////////////////////////////////////
//START - SET DATE RANGE
// === BACKTEST RANGE ===
FromMonth = input(defval = 1, title = "From Month", minval = 1)
FromDay = input(defval = 1, title = "From Day", minval = 1)
FromYear = input(defval = 2010, title = "From Year")
ToMonth = input(defval = 12, title = "To Month", minval = 1)
ToDay = input(defval = 31, title = "To Day", minval = 1)
ToYear = input(defval = 2020, title = "To Year")
startDate = time > timestamp(FromYear, FromMonth, FromDay, 1, 1)
endDate = time < timestamp(ToYear, ToMonth, ToDay, 23, 59)
withinTimeRange = true
/////////////////////////////////////////////////////////////
//END - SET DATE RANGE
/////////////////////////////////////////////////////////////
//START - INDICATORS
length = input(3)
mult = input(1, minval = 0.01)
atr_ = atr(length)
max1 = max(nz(max_[1]), close)
min1 = min(nz(min_[1]), close)
is_uptrend_prev = nz(is_uptrend[1], true)
stop = is_uptrend_prev ? max1 - mult * atr_ : min1 + mult * atr_
vstop_prev = nz(vstop[1])
vstop1 = is_uptrend_prev ? max(vstop_prev, stop) : min(vstop_prev, stop)
is_uptrend = close - vstop1 >= 0
is_trend_changed = is_uptrend != is_uptrend_prev
max_ = is_trend_changed ? close : max1
min_ = is_trend_changed ? close : min1
vstop = is_trend_changed ? is_uptrend ? max_ - mult * atr_ : min_ + mult * atr_ : vstop1
plot(vstop, color = is_uptrend ? yellow : red, style=circles, linewidth=2)
/////////////////////////////////////////////////////////////
//END - INDICATORS
/////////////////////////////////////////////////////////////
//START - TRADING RULES
direction = input(defval=1, title = "Strategy Direction", minval=-1, maxval=1)
strategy.risk.allow_entry_in(direction == 0 ? strategy.direction.all : (direction < 0 ? strategy.direction.short : strategy.direction.long))
condition1 = close > vstop and withinTimeRange
condition2 = close < vstop and withinTimeRange
strategy.entry("BUY", strategy.long, when = condition1)
strategy.entry("SELL", strategy.short, when = condition2)
/////////////////////////////////////////////////////////////
//END - TRADING RULESPublished by ChaoZhang on the FMZ strategy square · last modified 2024-02-05. 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/Momentum-Swing-Trading-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
- Advanced Multi Indicator Trend Following and Momentum Quantitative Trading StrategyPine Script · Momentum · 1h
- Cross Period Momentum EMA Strategy with RSI and Dynamic ATR Stop LossPine Script · Momentum · 1d
- Dual EMA Crossover with RSI Momentum Enhanced Trading StrategyPine Script · Momentum · 1d
- Dual EMA Momentum Trend Trading Strategy with Full Body Candle Signal SystemPine Script · Momentum · 2h
- Dynamic Trend Channel and Relative Strength Momentum Trading StrategyPine Script · Momentum · 3h
- KST EMA Momentum Trend Following StrategyPine Script · Momentum · 1d