Strategy vault / Trend following
EMA Tracking Trend Suppressing Oscillation Strategy
This strategy combines the advantages of three indicators: EMA, Trend Tracking Strategy (TTS) and Schaff Trend Cycle (STC) to form a strong short-term trend tracking strategy. Specifically, the strategy will judge…

Overview
This strategy combines the advantages of three indicators: EMA, Trend Tracking Strategy (TTS) and Schaff Trend Cycle (STC) to form a strong short-term trend tracking strategy. Specifically, the strategy will judge whether the buy and sell signals of the three indicators are consistent. If they are consistent, trading signals will be generated; otherwise no trades will be made. This filters out some false signals and makes the strategy more reliable.
Strategy Principle
The strategy consists of three main parts: EMA indicator, TTS trend tracking strategy and STC indicator.
Firstly, the 200-period EMA exponential moving average line is calculated. If the price is below this EMA line, the EMA indicator gives a sell signal: -1; if the price is above the line, the EMA indicator gives a buy signal: 1.
Secondly, the relevant parameters of the TTS trend tracking strategy are calculated. According to the price breakouts of the upper and lower rails, the market trend direction is determined. If the price breaks through the upper rail, a buy signal 1 is generated; if the price breaks through the lower rail, a sell signal -1 is generated.
Finally, the Schaff Trend Cycle (STC) indicator is calculated, which reflects the change trend of the price consolidation. If the STC indicator rises, it generates a buy signal 1; if the STC indicator falls, it generates a sell signal -1.
After obtaining the judgment signals from the three indicators, the strategy will determine whether they are consistent. Only when all three indicator judgment signals are consistent will actual trading signals be generated. This can effectively filter out some false signals and make the strategy more reliable.
Once determining to generate trading signals, long or short positions will be opened and stop-profit/stop-loss points will be set.
Advantages
The strategy combines three different types of indicators to effectively determine market trend direction.
Using the consistency of judgment signals from three indicators to filter out false signals can reduce unnecessary trades and make the strategy more reliable.
Setting reasonable stop-profit/stop-loss points can lock in profits and prevent losses from expanding.
The optimized parameters are suitable for most stocks and forex products.
Simple and easy-to-understand trading logic.
Risks
Inconsistency between indicator judgments may cause loss of trading opportunities. Judgment rules can be further optimized.
STC indicator is sensitive to parameters. Different products need parameter tuning.
In downtrends, stop loss may be penetrated, causing huge losses. Adaptive stop loss can be considered.
Sideway consolidations cannot be effectively identified, leading to trap positions.
Enhancements
Test more indicator combinations to find stronger judgment rules, e.g. adding RSI indicator.
Optimize STC parameters for better adaptation across different products. Add adaptive parameter optimization module.
Increase adaptive stop loss module to optimize stop loss points dynamically.
Enhance position closing module to identify sideway ranges and avoid traps.
Optimize algorithms for high frequency trading, reducing latency and improving order fulfillment rates.
Conclusion
The strategy combines EMA, TTS and STC indicators to determine market direction, with consistent judgments from all three triggering trades, effectively filtering out false signals. There is still large room for optimizations, e.g. testing more indicator combinations, adding adaptive algorithms, optimizing high frequency trading modules, etc, to further strengthen trend tracking capability. Compared to traditional strategies simply following moving averages, this strategy can judge markets more intelligently, capture trends while avoiding traps.
Parameters
| Name | Default | What it controls |
|---|---|---|
| v_input_float_1 | 0.1 | (?Strategy)Profit % |
| v_input_int_1 | 21 | (?Trend Trader Strategy)Length |
| v_input_float_2 | 3 | Multiplier |
| v_input_int_2 | 12 | (?Schaff Trend Cycle)Length |
| v_input_int_3 | 26 | FastLength |
| v_input_int_4 | 50 | SlowLength |
| v_input_float_3 | 0.5 | AAA |
Source Pine Script
/*backtest
start: 2022-12-05 00:00:00
end: 2023-04-14 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ajahanbin1374
//@version=5
strategy(title = "EMA + TTS + STC", shorttitle = "EMA + TTS + STC", overlay = true, calc_on_order_fills=false, calc_on_every_tick = false, initial_capital = 100, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, commission_value = 0.01)
////////////////////////////////////////////////////////////
// Strategy entry
////////////////////////////////////////////////////////////
profit = input.float(defval = 0.1, minval = 0.0, title="Profit %", step=0.01, group = "Strategy") * 0.01
////////////////////////////////////////////////////////////
// Emponential Moving Average
////////////////////////////////////////////////////////////
ema = ta.ema(close, 200)
posEma = close < ema ? -1 : 1
////////////////////////////////////////////////////////////
// Trend Trader Strategy
////////////////////////////////////////////////////////////
Length = input.int(21, minval=1, group="Trend Trader Strategy")
Multiplier = input.float(3, minval=0.000001, group="Trend Trader Strategy")
avgTR = ta.wma(ta.atr(1), Length)
highestC = ta.highest(Length)
lowestC = ta.lowest(Length)
hiLimit = highestC[1] - avgTR[1] * Multiplier
loLimit = lowestC[1] + avgTR[1] * Multiplier
ret = 0.0
posTts = 0.0
ret:= close > hiLimit and close > loLimit ? hiLimit :
close < loLimit and close < hiLimit ? loLimit : nz(ret[1], close)
posTts:= close > ret ? 1 :close < ret ? -1 : nz(posTts[1], 0)
////////////////////////////////////////////////////////////
// Schaff Trend Cycle (STC)
////////////////////////////////////////////////////////////
EEEEEE = input.int(12, 'Length', group ="Schaff Trend Cycle")
BBBB = input.int(26, 'FastLength', group ="Schaff Trend Cycle")
BBBBB = input.int(50, 'SlowLength', group ="Schaff Trend Cycle")
AAAA(BBB, BBBB, BBBBB) =>
fastMA = ta.ema(BBB, BBBB)
slowMA = ta.ema(BBB, BBBBB)
AAAA = fastMA - slowMA
AAAA
AAAAA(EEEEEE, BBBB, BBBBB) =>
AAA = input.float(0.5, group ="Schaff Trend Cycle")
var CCCCC = 0.0
var DDD = 0.0
var DDDDDD = 0.0
var EEEEE = 0.0
BBBBBB = AAAA(close, BBBB, BBBBB)
CCC = ta.lowest(BBBBBB, EEEEEE)
CCCC = ta.highest(BBBBBB, EEEEEE) - CCC
CCCCC := CCCC > 0 ? (BBBBBB - CCC) / CCCC * 100 : nz(CCCCC[1])
DDD := na(DDD[1]) ? CCCCC : DDD[1] + AAA * (CCCCC - DDD[1])
DDDD = ta.lowest(DDD, EEEEEE)
DDDDD = ta.highest(DDD, EEEEEE) - DDDD
DDDDDD := DDDDD > 0 ? (DDD - DDDD) / DDDDD * 100 : nz(DDDDDD[1])
EEEEE := na(EEEEE[1]) ? DDDDDD : EEEEE[1] + AAA * (DDDDDD - EEEEE[1])
EEEEE
mAAAAA = AAAAA(EEEEEE, BBBB, BBBBB)
mColor = mAAAAA > mAAAAA[1] ? color.new(color.green, 20) : color.new(color.red, 20)
posStc = mAAAAA > mAAAAA[1] ? 1 : -1
////////////////////////////////////////////////////////////
// Strategy entry
////////////////////////////////////////////////////////////
pos = posEma == 1 and posTts == 1 and posStc == 1 ? 1 : posEma == -1 and posTts == -1 and posStc == -1 ? -1 : 0
currentPostition = strategy.position_size > 0 ? 1 : strategy.position_size < 0 ? -1 : 0
noOpenPosition = strategy.position_size == 0
signal = pos != pos[1] and pos == 1 and noOpenPosition ? 1 : pos != pos[1] and pos == -1 and noOpenPosition ? -1 : 0
stopPriceForLong = math.min(close * (1 - profit), low[1] * 0.9998, low[2] * 0.9998)
limitPriceForLong = close + (close - stopPriceForLong)
stopPriceForShort = math.max(close * (1 + profit), high[1] * 1.0002, high[2] * 1.0002)
limitPriceForShort = close - (stopPriceForShort - close)
if signal == 1
strategy.entry(id="L", direction=strategy.long)
strategy.exit(id='EL', from_entry='L', limit=limitPriceForLong, stop=stopPriceForLong)
if signal == -1
strategy.entry(id="S", direction=strategy.short)
strategy.exit(id='ES', from_entry='S', limit=limitPriceForShort, stop=stopPriceForShort)
////////////////////////////////////////////////////////////
// Plots - Debuger
////////////////////////////////////////////////////////////
plotchar(signal, title='singal', char = '')
plotchar(posEma, title='posEma', char = '')
plotchar(posTts, title='posTts', char = '')
plotchar(pos, title='pos', char = '')
plotchar(currentPostition, title = 'currentPostition', char='')
plotchar(stopPriceForLong, title = "stopPriceForLong", char ='')
plotchar(limitPriceForLong, title = 'limitPriceForLong', char='')
plotchar(stopPriceForShort, title = "stopPriceForShort", char ='')
plotchar(limitPriceForShort, title = 'limitPriceForShort', char='')
////////////////////////////////////////////////////////////
// Plots
////////////////////////////////////////////////////////////
plot(ret, color=color.new(color.black, 0), title='Trend Trader Strategy')
plotchar(mAAAAA, color=mColor, title='STC', location = location.bottom, char='-', size=size.normal)
plot(series = ema, title = "ema")
Published by ChaoZhang on the FMZ strategy square · last modified 2023-12-12. 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/EMA-Tracking-Trend-Suppressing-Oscillation-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
- ATR Dynamic Trend Following and EMA Crossover Trading StrategyPine Script · Trend following · 1d
- ATR and Moving Average Crossover Hybrid StrategyPine Script · Trend following · 1h
- ATR and T3 Moving Average StrategyPine Script · Trend following · 5m
- Adaptive ATR and RSI Trend Following Strategy with Trailing Stop LossPine Script · Trend following · 1h
- Bollinger Bands and RSI Trend Following StrategyPine Script · Trend following · 1h
- Dual ATR Channel Trend Following StrategyPine Script · Trend following · 15m