0bps

Strategy vault / Trend following

Dual Trend Lines Intelligent Tracking BTC Investment Strategy

This strategy is mainly used for the automated long-term investment in BTC. It uses the crossover of dual EMA and LSMA to determine the trend direction and uses the ATR indicator to calculate a dynamic stop loss to…

Author
ChaoZhang
Complexity
Intermediate · 121 lines
Parameters
19

IMG

Overview

This strategy is mainly used for the automated long-term investment in BTC. It uses the crossover of dual EMA and LSMA to determine the trend direction and uses the ATR indicator to calculate a dynamic stop loss to effectively track the BTC bullish trend.

Strategy Logic

  1. Use 25-period EMA and 100-period LSMA to form a dual moving average. Their crossover is used to determine the market trend. The EMA responds quickly to price changes while the LSMA filters out false breakouts.

  2. When the fast EMA crosses above the slow LSMA, it is determined that the uptrend is still intact and long positions are taken. On the contrary, when the fast EMA crosses below the slow LSMA, it is determined that a downtrend has begun and existing positions are closed.

  3. After taking long positions, the dynamic stop loss calculated using the ATR indicator keeps adjusting to effectively track the uptrend of BTC. Specifically, the initial point of the stop loss line is the entry price. After that, each adjustment will slide up by a fixed percentage of the ATR amplitude.

  4. The stop loss line can effectively lock in the floating profit brought by the BTC uptrend, while preventing the stop loss point from getting too close to the latest price to avoid frequent stop loss. In addition, the strategy also sets two moving stop profits of different proportions to lock in more profits.

Advantage Analysis

  1. Using dual moving averages to determine the trend is more reliable and can effectively prevent false signals.

  2. The ATR dynamic trailing stop loss can lock in most profits while avoiding frequent small stop losses.

  3. No matter whether the bullish trend ends or not, as long as the moving average issues an exit signal, the position will be stopped out to control risks.

  4. The strategy has a high degree of automation without manual intervention, making it suitable for long-term live trading.

Risk Analysis

  1. Still need to pay attention to sudden major news to avoid huge slippage losses.

  2. Although the combination of dual moving averages can reduce false signals, it is still difficult to completely avoid them in range-bound markets.

  3. Improper parameter settings of ATR can also affect the stop loss effect. Adjustments are needed based on different products.

  4. Unreasonable moving average periods or failure to update them in time can lead to signal lag.

  5. Ensure server stability to avoid abnormal crashes that interrupt automated trading.

Optimization Directions

  1. More indicators such as Bollinger Bands can be added to determine the trend. Machine learning models can also be used to predict prices.

  2. The calculation method of the ATR dynamic stop loss can also be adjusted and optimized to make the stop loss smoother.

  3. Trading volume based alert mechanisms and intraday rotation features can be added to guard against impacts from major news.

  4. Parameters vary for different coins. More historical data can be used to train personalized parameters.

Summary

Overall, this is a very practical automated BTC investment program. Using dual EMAs to determine the major trend is very reliable. With ATR trailing stop loss, it can achieve decent profits and the validity period can be very long. As parameters continue to be optimized, there is still much room for improvement in the performance of this strategy. It is well worth live trading verification.

Parameters

NameDefaultWhat it controls
v_input_10What trades should be taken : : LONG | SHORT | BOTH | NONE
v_input_20First Trend Line : : TEMA | LSMA | EMA | SMA
v_input_30First Trend Line : : LSMA | TEMA | EMA | SMA
v_input_425Length of the First Trend Line
v_input_5100Length of the Second Trend Line
v_input_615Long Take Profit 1 %
v_input_720Long Take Profit 1 Qty
v_input_830Long Take Profit 2%
v_input_920Long Take Profit 2 Qty
v_input_105stop loss in %
v_input_113.5SL Mutiplier
v_input_128ATR period
v_input_13_close0Source: close | high | low | open | hl2 | hlc3 | hlcc4 | ohlc4
v_input_142016Backtest Start Year
v_input_15trueBacktest Start Month
v_input_16trueBacktest Start Day
v_input_179999Backtest Stop Year
v_input_1812Backtest Stop Month
v_input_1931Backtest Stop Day

Source Pine Script

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Wunderbit Trading

//@version=4
strategy("Automated Bitcoin (BTC) Investment Strategy", overlay=true, initial_capital=5000,pyramiding = 0, currency="USD", default_qty_type=strategy.percent_of_equity, default_qty_value=100,  commission_type=strategy.commission.percent,commission_value=0.1)

////////////  Functions

Atr(p) =>
    atr = 0.
    Tr = max(high - low, max(abs(high - close[1]), abs(low - close[1])))
    atr := nz(atr[1] + (Tr - atr[1])/p,Tr)

//TEMA
TEMA(series, length) =>
    if (length > 0)
        ema1 = ema(series, length)
        ema2 = ema(ema1, length)
        ema3 = ema(ema2, length)
        (3 * ema1) - (3 * ema2) + ema3
    else
        na
tradeType = input("LONG", title="What trades should be taken : ", options=["LONG", "SHORT", "BOTH", "NONE"])

///////////////////////////////////////////////////
/// INDICATORS
source=close

/// TREND
trend_type1 = input("TEMA", title ="First Trend Line : ", options=["LSMA", "TEMA","EMA","SMA"])
trend_type2 = input("LSMA", title ="First Trend Line : ", options=["LSMA", "TEMA","EMA","SMA"])

trend_type1_length=input(25, "Length of the First Trend Line")
trend_type2_length=input(100, "Length of the Second Trend Line")

leadLine1 = if trend_type1=="LSMA"
    linreg(close, trend_type1_length, 0)
else if trend_type1=="TEMA"
    TEMA(close,trend_type1_length)
else if trend_type1 =="EMA"
    ema(close,trend_type1_length)
else
    sma(close,trend_type1_length)

leadLine2 = if trend_type2=="LSMA"
    linreg(close, trend_type2_length, 0)
else if trend_type2=="TEMA"
    TEMA(close,trend_type2_length)
else if trend_type2 =="EMA"
    ema(close,trend_type2_length)
else
    sma(close,trend_type2_length)

p3 = plot(leadLine1, color= #53b987, title="EMA", transp = 50, linewidth = 1)
p4 = plot(leadLine2, color= #eb4d5c, title="SMA", transp = 50, linewidth = 1)
fill(p3, p4, transp = 60, color = leadLine1 > leadLine2 ? #53b987 : #eb4d5c)

//Upward Trend
UT=crossover(leadLine1,leadLine2)
DT=crossunder(leadLine1,leadLine2)

// TP/ SL/  FOR LONG
// TAKE PROFIT AND STOP LOSS
long_tp1_inp = input(15, title='Long Take Profit 1 %', step=0.1)/100
long_tp1_qty = input(20, title="Long Take Profit 1 Qty", step=1)

long_tp2_inp = input(30, title='Long Take Profit 2%', step=0.1)/100
long_tp2_qty = input(20, title="Long Take Profit 2 Qty", step=1)

long_take_level_1 = strategy.position_avg_price * (1 + long_tp1_inp)
long_take_level_2 = strategy.position_avg_price * (1 + long_tp2_inp)

long_sl_input = input(5, title='stop loss in %', step=0.1)/100
long_sl_input_level = strategy.position_avg_price * (1 - long_sl_input)

// Stop Loss
multiplier = input(3.5, "SL Mutiplier", minval=1, step=0.1)
ATR_period=input(8,"ATR period", minval=1, step=1)

// Strategy
//LONG STRATEGY CONDITION

SC = input(close, "Source", input.source)
SL1 = multiplier * Atr(ATR_period)  // Stop Loss
Trail1 = 0.0
Trail1 :=  iff(SC < nz(Trail1[1], 0) and SC[1] < nz(Trail1[1], 0), min(nz(Trail1[1], 0), SC + SL1), iff(SC > nz(Trail1[1], 0), SC - SL1, SC + SL1))
Trail1_high=highest(Trail1,50)

// iff(SC > nz(Trail1[1], 0) and SC[1] > nz(Trail1[1], 0), max(nz(Trail1[1], 0), SC - SL1),

entry_long=crossover(leadLine1,leadLine2) and Trail1_high < close
exit_long = close < Trail1_high or crossover(leadLine2,leadLine1) or close < long_sl_input_level

///// BACKTEST PERIOD ///////
testStartYear = input(2016, "Backtest Start Year")
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear, testStartMonth, testStartDay, 0, 0)

testStopYear = input(9999, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear, testStopMonth, testStopDay, 0, 0)

testPeriod() =>
    time >= testPeriodStart and time <= testPeriodStop ? true : false

if testPeriod()
    if tradeType=="LONG" or tradeType=="BOTH"
        if strategy.position_size == 0 or strategy.position_size > 0
            strategy.entry("long", strategy.long, comment="b8f60da7_ENTER-LONG_BINANCE_BTC/USDT_b8f60da7-BTC-Investment_4H", when=entry_long)
            strategy.exit("TP1", "long", qty_percent=long_tp1_qty, limit=long_take_level_1)
            strategy.exit("TP2", "long", qty_percent=long_tp2_qty, limit=long_take_level_2)
            strategy.close("long", when=exit_long, comment="b8f60da7_EXIT-LONG_BINANCE_BTC/USDT_b8f60da7-BTC-Investment_4H" )


// LONG POSITION

plot(strategy.position_size > 0 ? long_take_level_1 : na, style=plot.style_linebr, color=color.green, linewidth=1, title="1st Long Take Profit")
plot(strategy.position_size > 0 ? long_take_level_2 : na, style=plot.style_linebr, color=color.green, linewidth=1, title="2nd Long Take Profit")
plot(strategy.position_size > 0 ? Trail1_high : na, style=plot.style_linebr, color=color.red, linewidth=1, title="Long Stop Loss")

Published by ChaoZhang on the FMZ strategy square · last modified 2023-11-22. 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.

in Claude Code, Cursor, Codex & 4 more
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Dual-Trend-Lines-Intelligent-Tracking-BTC-Investment-Strategy.md
  1. npx agenkit install engineering-kit in your project
  2. Paste the command into your agent and approve each phase
  3. 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

esc

Try , , or .

↑↓ move↵ open