Strategy vault / Trend following
Dynamic Position Rebalancing Trend Tracking System
This strategy integrates the exponential moving average crossover system and turtle trading system, two popular systematic trading strategies. It is specially designed for the daily timeframe to track market trends…

Overview
This strategy integrates the exponential moving average crossover system and turtle trading system, two popular systematic trading strategies. It is specially designed for the daily timeframe to track market trends in real-time by dynamically managing positions.
Strategy Logic
The strategy contains two sub-strategies: trend strategy and breakout strategy.
The trend strategy uses fast EMA and slow EMA crossovers as trading signals. The fast EMA period is user-defined and the slow EMA period is 5 times of the fast EMA. The signal is generated by dividing the EMA difference by the 252-period return standard deviation, which is volatility-adjusted to produce more reliable signals. It goes long or short when detecting new trend formations.
The breakout strategy uses the average of highest high and lowest low prices over a fixed lookback period as the baseline. Long/short signals are generated when the price breaks out above/below the baseline by a certain percentage.
Position sizing is based on recent price volatility and user-defined annual risk target. Larger size is taken when volatility is low while smaller size is taken when volatility is high. This realizes dynamic position management with risk adjustment.
Hard stops are set as multiples of the average true range. Trailing stops trail recent highest high or lowest low prices.
Advantage Analysis
The main advantages of this strategy include:
Combining trend tracking and breakout sub-strategies adapts to different market environments with strong robustness.
Applying advanced position sizing and risk management techniques dynamically manages position and effectively controls risk.
Volatility-adjusting positions based on recent volatility and annual risk target maintains relatively stable portfolio risk across high/low volatility regimes.
Setting stop loss based on actual price fluctuation avoids unnecessary small losses from stop runs.
Adjusting trailing stop in real-time flexibly follows trends to book profits and stops out timely.
Risk Analysis
The main risks of this strategy are:
Reliance on parameter optimization. Different parameters considerably impact strategy performance so comprehensive testing is needed to find optimum parameters.
Frequent stop outs in choppy trends. Stop loss width could be relaxed and stop mechanisms optimized.
Sensitivity to initial capital and trading costs. Insufficient initial capital and high trading costs negatively impact profitability.
Reliance on accurate volatility estimates for position sizing and risk controls. Inaccurate volatility estimates lead to oversized or undersized positions.
Optimization Directions
The main optimization directions include:
Search for optimal parameter sets via more backtesting with larger historical dataset.
Improve stop mechanisms by testing various stops like moving stops, time stops, volatility stops etc.
Optimize position sizing and risk management by testing different risk targets to find best risk-return profile. Also test impacts of different leverage levels.
Try more auxiliary indicators to improve signal accuracy and strategy robustness.
Test different holding periods by assisting decisions with higher timeframe signals to improve position allocation accuracy.
Conclusion
This strategy integrates two major categories of trading strategies: trend following and breakouts. By applying advanced dynamic position adjustment techniques, it effectively controls risk while tracking market moves to profit. It demonstrates strong profit potential and is worth further testing and optimization.
Parameters
| Name | Default | What it controls |
|---|---|---|
| v_input_1_close | 0 | (?Strategy Settings)Source: close | high | low | open | hl2 | hlc3 | hlcc4 | ohlc4 |
| v_input_int_1 | 10 | Lookback period for fast EMA |
| v_input_int_2 | 20 | Lookback period for Breakout |
| v_input_2 | true | (?Strategy toggle)Long |
| v_input_3 | true | Short |
| v_input_4 | false | Trend |
| v_input_5 | true | Breakout |
| v_input_float_1 | 2 | (?Risk Management Settings)Stop multiple |
| v_input_int_3 | 10 | Trail lookback |
| v_input_float_2 | true | Max Leverage |
| v_input_float_3 | 15 | Annualised Volatility Target % |
| v_input_6 | true | Compounding |
| v_input_float_4 | 50 | % |
| v_input_int_4 | true | (?Backtest range)From Day |
| v_input_int_5 | true | From Mon |
| v_input_int_6 | 2018 | From Yr |
| v_input_int_7 | true | To Day |
| v_input_int_8 | true | To Mon |
| v_input_int_9 | 9999 | To Yr |
Source Pine Script
/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
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 https://mozilla.org/MPL/2.0/
// © Crunchster1
//@version=5
strategy(title="Crunchster's Turtle and Trend System", shorttitle="Turtle Trend", overlay=true, slippage=10, pyramiding=1, precision = 4, calc_on_order_fills = false, calc_on_every_tick = false, default_qty_value = 0.1, initial_capital = 1000, commission_value = 0.06, process_orders_on_close = true)
// Inputs and Parameters
src = input(close, 'Source', group='Strategy Settings')
length = input.int(title="Lookback period for fast EMA", defval=10, minval=2, group='Strategy Settings', tooltip='This sets the lookback period for the fast exponential moving average. The slow EMA is 5x the fast EMA length')
blength = input.int(title="Lookback period for Breakout", defval=20, minval=5, step=5, group='Strategy Settings')
long = input(true, 'Long', inline='08', group='Strategy toggle')
short = input(true, 'Short', inline='08', group='Strategy toggle', tooltip='Toggle long/short strategy on/off')
EMAwt = input(false, 'Trend', inline='01', group='Strategy toggle')
breakwt = input(true, 'Breakout', inline='01', group='Strategy toggle', tooltip='Toggle trend/breakout strategy on/off')
stopMultiple = input.float(2, 'Stop multiple', step=0.5, group='Risk Management Settings', tooltip='Multiple for ATR, setting hard stop loss from entry price')
trail = input.int(10, 'Trail lookback', step=5, group='Risk Management Settings', tooltip='Lookback period for the trailing stop')
lev = input.float(1, 'Max Leverage', step=0.5, group='Risk Management Settings', tooltip='Max leverage sets maximum allowable leverage of total capital (initial capital + any net profit), capping maximum volatility adjusted position size')
riskT = input.float(15, maxval=75, title='Annualised Volatility Target %', group='Risk Management Settings', tooltip='Specify annual risk target, used to determine volatility adjusted position size. Annualised daily volatility is referenced to this value and position size adjusted accordingly')
comp = input(true, 'Compounding', inline='09', group='Risk Management Settings')
Comppct = input.float(50, '%', step=5, inline='09', group='Risk Management Settings', tooltip='Toggle compounding of profit, and set % of profit to compound')
// Backtesting period
FromDay = input.int(defval=1, title='From Day', minval=1, maxval=31, inline='04', group='Backtest range')
FromMonth = input.int(defval=1, title='From Mon', minval=1, maxval=12, inline='04', group='Backtest range')
FromYear = input.int(defval=2018, title='From Yr', minval=1900, inline='04', group='Backtest range', tooltip='Set start of backtesting period')
ToDay = input.int(defval=1, title='To Day', minval=1, maxval=31, inline='05', group='Backtest range')
ToMonth = input.int(defval=1, title='To Mon', minval=1, maxval=12, inline='05', group='Backtest range')
ToYear = input.int(defval=9999, title='To Yr', minval=1900, inline='05', group='Backtest range', tooltip='Set end of backtesting period')
start = timestamp(FromYear, FromMonth, FromDay, 00, 00)
finish = timestamp(ToYear, ToMonth, ToDay, 23, 59)
window = time >= start and time <= finish
// Breakout strategy
lower = ta.lowest(low[1], blength)
upper = ta.highest(high[1], blength)
basis = math.avg(upper, lower)
signal = 20*(close - basis) / (upper - lower)
// Trend strategy
fEMA = ta.ema(close[1], length)
sEMA = ta.ema(close[1], length*5)
emadiff = fEMA - sEMA
nemadiff = 5*emadiff/(ta.stdev(close - close[1], 252))
//Risk Management formulae
strategy.initial_capital = 50000
tr = math.max(high - low, math.abs(high - close), math.abs(low - close)) //True range
stopL = ta.sma(tr, 14) //Average true range
stdev = ta.stdev(close-close[1], 14) //volatility of recent returns
maxcapital = strategy.initial_capital+strategy.netprofit //Maximum capital available to invest - initial capital net of profit
annvol = 100*math.sqrt(365)*stdev/close //converts recent volatility of returns into annualised volatility of returns - assumes daily timeframe
risk = 1.1
if comp
risk := (strategy.initial_capital+(Comppct*strategy.netprofit/100))//adjust investment capital to include compounding
else
risk := strategy.initial_capital
shares = (risk * (riskT/annvol)) / close //calculates volatility adjusted position size, dependent on user specified annualised risk target
if ((shares*close) > lev*maxcapital) //ensures position size does not exceed available capital multiplied by user specified maximum leverage
shares := lev*maxcapital/close
//To set the price at the entry point of trade
Posopen() =>
math.abs(strategy.position_size[1]) <= 0 and math.abs(strategy.position_size) > 0
var float openN = na
if Posopen()
openN := stopL
// Trailing stop
tlower = ta.lowest(low[1], trail)
tupper = ta.highest(high[1], trail)
tbasis = math.avg(tupper, tlower)
tsignal = 20*(close - tbasis) / (tupper - tlower)
// Strategy Rules
if EMAwt
if long
longCondition2 = (nemadiff >2 and nemadiff[1] <2) and window
exitlong = tsignal <= -10
if (longCondition2)
strategy.entry('Trend Long!', strategy.long, qty=shares)
if strategy.position_size > 0
strategy.exit('Stop Long', from_entry = 'Trend Long!', stop=(strategy.opentrades.entry_price(0) - (openN * stopMultiple)))
if (exitlong)
strategy.close('Trend Long!', immediately = true)
if short
shortCondition2 = (nemadiff <-1 and nemadiff[1] >-1) and window
exitshort = tsignal >= 10
if (shortCondition2)
strategy.entry('Trend Short!', strategy.short, qty=shares)
if strategy.position_size < 0
strategy.exit('Stop Short', from_entry = 'Trend Short!', stop=(strategy.opentrades.entry_price(0) + (openN * stopMultiple)))
if (exitshort)
strategy.close('Trend Short!', immediately = true)
if breakwt
if long
longCondition1 = (signal >= 10) and window
exitlong = tsignal <= -10
if (longCondition1)
strategy.entry('Break Long!', strategy.long, qty=shares)
if strategy.position_size > 0
strategy.exit('Stop Long', from_entry = 'Break Long!', stop=(strategy.opentrades.entry_price(0) - (openN * stopMultiple)))
if (exitlong)
strategy.close('Break Long!', immediately = true)
if short
shortCondition1 = (signal <= -10) and window
exitshort = tsignal >= 10
if (shortCondition1)
strategy.entry('Break Short!', strategy.short, qty=shares)
if strategy.position_size < 0
strategy.exit('Stop Short', from_entry = 'Break Short!', stop=(strategy.opentrades.entry_price(0) + (openN * stopMultiple)))
if (exitshort)
strategy.close('Break Short!', immediately = true)
// Visuals of trend and direction
plot(nemadiff, title='EMA Forecast', color=color.black, display=display.none)
plot(ta.sma(ta.median(math.sqrt(math.pow(nemadiff,2)), 700), 350), 'Forecast mean', color=color.rgb(245, 0, 0), display=display.none)
MAColor = fEMA > sEMA ? #00ff00 : #ff0000
MA1 = plot(fEMA, title='Fast EMA', color=MAColor)
MA2 = plot(sEMA, title='Slow EMA', color=MAColor)
fill(MA1, MA2, title='Band Filler', color=MAColor)Published by ChaoZhang on the FMZ strategy square · last modified 2024-01-26. 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/Dynamic-Position-Rebalancing-Trend-Tracking-System.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 and Moving Average Crossover Hybrid StrategyPine 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
- Dual MA Crossover Trend Tracking StrategyPine Script · Trend following · 1h
- Dual Mode Adaptive Trend Trading Strategy EMA Crossover with ATR Volatility Based Risk Management SystemPine Script · Trend following · 1d
- Dual Moving Average Crossover Dynamic Position Optimization Strategy with EMA Cross Signal SystemPine Script · Trend following · 1h