0bps

Strategy vault / Trend following

Golden Cross Keltner Channel Trend Following Strategy

The Golden Cross Keltner Channel Trend Following Strategy is a strategy that only trades in the direction of the trend. It combines the moving average golden cross and Keltner Channel as entry signals to capture the…

Author
ChaoZhang
Complexity
Intermediate · 123 lines
Parameters
14
Backtest bar
1d · swing
Tested on
BTC/USDT · futures

IMG

Overview

The Golden Cross Keltner Channel Trend Following Strategy is a strategy that only trades in the direction of the trend. It combines the moving average golden cross and Keltner Channel as entry signals to capture the trend direction.

Principle

This strategy uses two moving averages, a short-term and a long-term moving average, to form golden crosses and death crosses to determine the trend direction. At the same time, it uses user-defined multiples to plot the upper and lower rails of the Keltner Channel and generate trading signals when prices break through the channel.

Specifically, the strategy first checks if the long-term moving average is above the short-term moving average, indicating a golden cross and an upward trend. If the short-term MA is below the long-term MA, it is a death cross, indicating a downward trend.

Based on the trend determination, if the price breaks above the upper rail, a long signal is generated. If the price breaks below the lower rail, a short signal is generated. Users can adjust the MA periods and channel width to customize the strategy parameters.

After entry, the strategy uses user-defined ATR multiples for take-profit and stop-loss. It also provides additional break-even and stop-loss conditions for more flexible position control.

Advantage Analysis

This strategy combines the advantages of trend following and channel breakouts, enabling effective trend identification and opportunity capturing. The main advantages are:

  1. Golden cross filters out false signals not aligned with the major trend.

  2. Channel breakout with trend direction improves entry accuracy.

  3. Take-profit and stop-loss preserve profits and control risks.

  4. Flexible parameter adjustments suit different products and environments.

  5. Goes both long and short, expanding applicability.

Risk Analysis

Despite the advantages, some risks need attention:

  1. Missing reversal opportunities.

  2. Trend changes may lead to losses.

  3. Improper parameters may cause over-trading or sparse trading.

  4. Overnight risk exists.

  5. Curve fitting risk.

Solutions include parameter optimization, timely MA period adjustment, and position sizing control.

Optimization Directions

There is room for further improvements:

  1. Adding more indicators to build a multi-factor model and improve accuracy. E.g. MACD, RSI.

  2. Parameter optimization via machine learning for market adaptability.

  3. Dynamic take-profit and stop-loss rules to balance profitability and reward.

  4. Dynamic position sizing based on volatility.

  5. Research optimal parameters for different products.

  6. Reduce trading frequency to minimize fees.

Conclusion

The Golden Cross Keltner Channel Trend Following Strategy is generally a stable and reliable trend following system. By combining trend filtering and channel breakouts, it identifies high-probability opportunities aligned with the trend direction. Further optimizations and enhancements can make it a robust trading framework.

Parameters

NameDefaultWhat it controls
v_input_121MA Length
v_input_2trueEntry ATR
v_input_34Profit Taker
v_input_4-1Exit ATR
v_input_string_10Moving Average Type: SMA | EMA | WMA
v_input_5trueLong Positions
v_input_6trueEnable Short Positions
v_input_750Short MA for Golden Cross
v_input_8200Long MA for Golden Cross
v_input_9trueEnable Long Profit Taker
v_input_10trueEnable Long Stop
v_input_11trueEnable Short Profit Taker
v_input_12trueEnable Short Stop
v_input_13trueEnable Take Profit Condition

Source Pine Script

/*backtest
start: 2022-10-26 00:00:00
end: 2023-11-01 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/
// © OversoldPOS

//@version=5
// strategy("Keltner Channel Strategy by OversoldPOS", overlay=true,initial_capital = 100000,default_qty_type = strategy.percent_of_equity,default_qty_value = 10, commission_type = strategy.commission.cash_per_order, commission_value = 7)

// Parameters
length = input(21, title="MA Length")
Entrymult = input(1, title="Entry ATR")
profit_mult = input(4, title="Profit Taker")
exit_mult = input(-1, title="Exit ATR")

// Moving Average Type Input
ma_type = input.string("SMA", title="Moving Average Type", options=["SMA", "EMA", "WMA"])

// Calculate Keltner Channels for different ATR multiples
atr_value = ta.atr(length)

basis = switch ma_type
    "SMA" => ta.sma(close, length)
    "EMA" => ta.ema(close, length)
    "WMA" => ta.wma(close, length)
 

//
EntryKeltLong = basis + Entrymult * ta.atr(10)
EntryKeltShort = basis - Entrymult * ta.atr(10)
upper_channel1 = basis + 1 * ta.atr(10)
lower_channel1 = basis - 1 * ta.atr(10)
upper_channel2 = basis + 2 * ta.atr(10)
lower_channel2 = basis - 2 * ta.atr(10)
upper_channel3 = basis + 3 * ta.atr(10)
lower_channel3 = basis - 3 * ta.atr(10)
upper_channel4 = basis + 4 * ta.atr(10)
lower_channel4 = basis - 4 * ta.atr(10)

// Entry condition parameters
long_entry_condition = input(true, title="Long Positions")
short_entry_condition = input(true, title="Enable Short Positions")

// Additional conditions for long and short entries
is_long_entry = ta.ema(close, 20) > ta.ema(close, 50)
is_short_entry = ta.ema(close, 20) < ta.ema(close, 50)

// Additional conditions for long and short entries
MAShort =  input(50, title="Short MA for Golden Cross")
MALong =  input(200, title="Long MA for Golden Cross")
is_long_entry2 = ta.ema(close, MAShort) > ta.ema(close, MALong)
is_short_entry2 = ta.ema(close, MAShort) < ta.ema(close, MALong)

// Exit condition parameters
long_exit_condition1_enabled = input(true, title="Enable Long Profit Taker")
long_exit_condition2_enabled = input(true, title="Enable Long Stop")
short_exit_condition1_enabled = input(true, title="Enable Short Profit Taker")
short_exit_condition2_enabled = input(true, title="Enable Short Stop")

// Take Profit condition parameters
take_profit_enabled = input(true, title="Enable Take Profit Condition")

Takeprofit = basis + profit_mult * atr_value
STakeprofit = basis - profit_mult * atr_value

// Long entry condition
long_condition = long_entry_condition and ta.crossover(close, EntryKeltLong) and is_long_entry2

// Short entry condition
short_condition = short_entry_condition and ta.crossunder(close, EntryKeltShort) and is_short_entry2

// Exit conditions
long_exit_condition1 = long_exit_condition1_enabled and close > Takeprofit
long_exit_condition2 = long_exit_condition2_enabled and close < basis + exit_mult * atr_value
short_exit_condition1 = short_exit_condition1_enabled and close < STakeprofit
short_exit_condition2 = short_exit_condition2_enabled and close > basis - exit_mult * atr_value

// Strategy logic
if (long_condition)
    strategy.entry("Long", strategy.long)
if (short_condition)
    strategy.entry("Short", strategy.short)

if (long_exit_condition1 or long_exit_condition2)
    strategy.close("Long")

if (short_exit_condition1 or short_exit_condition2)
    strategy.close("Short")

// Moving Averages
var float MA1 = na
var float MA2 = na

if (ma_type == "SMA")
    MA1 := ta.sma(close, MAShort)
    MA2 := ta.sma(close, MALong)
else if (ma_type == "EMA")
    MA1 := ta.ema(close, MAShort)
    MA2 := ta.ema(close, MALong)
else if (ma_type == "WMA")
    MA1 := ta.wma(close, MAShort)
    MA2 := ta.wma(close, MALong)

// Plotting Keltner Channels with adjusted transparency
transparentColor = color.rgb(255, 255, 255, 56)

plot(upper_channel1, color=transparentColor, title="Upper Channel 1")
plot(lower_channel1, color=transparentColor, title="Lower Channel 1")
plot(upper_channel2, color=transparentColor, title="Upper Channel 2")
plot(lower_channel2, color=transparentColor, title="Lower Channel 2")
plot(upper_channel3, color=transparentColor, title="Upper Channel 3")
plot(lower_channel3, color=transparentColor, title="Lower Channel 3")
plot(upper_channel4, color=transparentColor, title="Upper Channel 4")
plot(lower_channel4, color=transparentColor, title="Lower Channel 4")
plot(basis, color=color.white, title="Basis")
plot(MA1, color=color.rgb(4, 248, 216), linewidth=2, title="Middle MA")
plot(MA2, color=color.rgb(220, 7, 248), linewidth=2, title="Long MA")

Published by ChaoZhang on the FMZ strategy square · last modified 2023-11-02. 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/Golden-Cross-Keltner-Channel-Trend-Following-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