黄金交叉凯尔特通道趋势跟踪策略是一种仅在趋势方向上进行交易的策略。它结合了移动平均线黄金交叉和凯尔特通道作为入市信号,以捕捉趋势的方向。
该策略使用两个移动平均线,即短期移动平均线和长期移动平均线,形成黄金交叉和死亡交叉来判断趋势方向。同时,它利用用户定义的倍数绘制凯尔特通道的上下轨,当价格突破通道时产生交易信号。
具体来说,策略首先判断长期移动平均线是否位于短期移动平均线之上,如果是,则为黄金交叉,判断为趋势向上;如果短期移动平均线位于长期移动平均线之下,则为死亡交叉,判断为趋势向下。
在趋势判断的基础上,如果价格突破上轨,产生做多信号;如果价格跌破下轨,产生做空信号。用户可以自行调整移动平均线周期和通道宽度,从而调整策略的参数。
进场后,策略利用用户定义的止盈止损ATR倍数来设置止盈止损位。同时,策略还提供额外的突破止盈和止损条件,可以更灵活地控制仓位。
该策略结合趋势跟踪和通道突破的优点,可以有效判断市场走势和捕捉趋势机会。具体优势如下:
使用黄金交叉判断趋势方向,可以有效过滤掉不符合大趋势的噪音交易。
凯尔特通道突破结合趋势方向判断,可以提高入市的时机 accuracy。
止盈止损机制可以锁定利润,并主动控制风险。
策略参数可以灵活调整,适用于不同品种和市场环境。
可同时做多做空,扩大策略适用范围。
尽管该策略有许多优点,但也存在一定的风险需要注意:
会有一定的错过反转机会的风险。
如果大趋势发生变化,可能产生逆势亏损的风险。
参数设置不当可能导致过于宽松或过于频繁交易。
需承担一定的隔夜风险。
存在一定的曲线拟合风险。
对此,可以通过参数优化,适时调整移动平均线周期,或适当缩小仓位规模来降低风险。
该策略还有进一步优化的空间:
可以考虑加入更多判断指标,形成多因子模型,提高策略 accuracy。例如加入 MACD、RSI 等。
可以基于机器学习对参数进行优化,使其更符合不同市场环境。
可以考虑动态调整止盈止损条件,在保证利润的前提下追求更大收益。
可以根据波动率的变化动态调整仓位规模。
研究不同品种的参数偏好,制定适合不同品种的参数组合。
添加降低交易频率的机制,以减少交易费率的影响。
黄金交叉凯尔特通道趋势跟踪策略整体来说是一个比较稳定可靠的趋势跟踪策略。它结合趋势判断和通道突破的优势,可以有效识别市场趋势方向,选择高概率的交易机会。通过参数优化和机制改进,该策略可以成为一个强大的量化交易工具。
/*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")