Dual-directional Trend Tracking Strategy Based on Range Breakout

Author: ChaoZhang, Date: 2024-02-01 14:22:26
Tags:

img

Overview

This strategy calculates the last highest price (lastbull) and the last lowest price (lastbear). It then compares the current price with lastbull and lastbear to determine if the price has entered a certain range and thus generates trading signals. It goes long when the price rises over lastbull by a certain percentage, and goes short when the price falls below lastbear by a certain percentage.

Strategy Logic

The strategy first calculates the last highest price lastbull and the last lowest price lastbear. Then it calculates the change percentage ddl of current price close relative to lastbull, and the change percentage dds relative to lastbear.

When ddl is lower than the configured long signal threshold signallong, a long signal up is generated. When dds is higher than the configured short signal threshold signalshort, a short signal dn is generated.

Upon receiving long signal, it opens long position if the needlong parameter is true. Upon receiving short signal, it opens short position if the needshort parameter is true. The position size capital is calculated from account equity.

It closes long position when price rises after opening long, and closes short position when price falls after opening short.

Advantage Analysis

This strategy combines trend and range analysis. It can catch trends and generate trading signals from range breakouts. Compared to simple trend tracking strategies, it can quickly catch new trend direction after range breakout.

The parameters are highly configurable for different products. The trading time range can be configured to avoid significant events.

Risk Analysis

There is no stop loss mechanism in this strategy to limit the loss per trade. The position sizing can be impacted heavily by price fluctuation when the trading range is large.

Stop loss can be added to limit the per trade loss. The position sizing algorithm can be customized based on products to stabilize the position size.

Optimization Directions

  1. Add moving stop loss to control per trade loss risk
  2. Improve position sizing algorithm, e.g. use ATR, to stabilize position size
  3. Add filtering for entry signals, e.g. only enter when golden cross happens
  4. Trade multiple products with correlation to lower systemic risk

Summary

This strategy combines trend analysis and range breakout to generate trading signals, which can catch new trends and take advantage of range bound characteristics. The parameters are highly configurable for different products. There is large room for optimization to adapt more complex market environments.


/*backtest
start: 2023-01-25 00:00:00
end: 2024-01-31 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//Noro
//2019

//@version=4
strategy(title = "Noro's DDL Strategy", shorttitle = "DDL str", overlay = false, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, pyramiding = 3)

//Settings
needlong = input(true, title = "Long")
needshort = input(true, title = "Short")
capital = input(100, defval = 100, minval = 1, maxval = 10000, title = "Lot")
signalshort = input(3.0, title = "Short, %")
signallong = input(-3.0, title = "Long, %")
fromyear = input(1900, defval = 1900, minval = 1900, maxval = 2100, title = "From Year")
toyear = input(2100, defval = 2100, minval = 1900, maxval = 2100, title = "To Year")
frommonth = input(01, defval = 01, minval = 01, maxval = 12, title = "From Month")
tomonth = input(12, defval = 12, minval = 01, maxval = 12, title = "To Month")
fromday = input(01, defval = 01, minval = 01, maxval = 31, title = "From day")
today = input(31, defval = 31, minval = 01, maxval = 31, title = "To day")

//Levels
bull = close > close[1] ? 1 : 0
bear = close < close[1] ? 1 : 0
lastbull = 0.0
lastbull := bull ? close : lastbull[1]
lastbear = 0.0
lastbear := bear ? close : lastbear[1]

//Signals
ddl = ((close / lastbull) - 1) * 100
up = ddl < signallong
dds = ((close / lastbear) - 1) * 100
dn = dds > signalshort

//Lines
plot(dds, style = plot.style_area, color = color.red, transp = 0)
plot(ddl, style = plot.style_area, color = color.lime, transp = 0)
plot(0, color = color.black, linewidth = 2, transp = 0)

//Background
col = (up and needlong) or (dn and needshort) ? color.yellow : na
bgcolor(col, transp = 20)

//Orders
lot = 0.0
lot := strategy.position_size == 0 ? strategy.equity / close * capital / 100 : lot[1]
truetime = true
if up
    strategy.entry("Long", strategy.long, lot, when = needlong and truetime)
if dn
    strategy.entry("Short", strategy.short, lot, when = needshort and truetime)
if strategy.position_size > 0 and close > open
    strategy.entry("Close", strategy.short, 0)
if strategy.position_size < 0 and close < open
    strategy.entry("Close", strategy.long, 0)

More