
意向反转包络均值策略是一种基于移动均线的意向反转交易策略。该策略使用双指数移动均线作为基础计算,并在其上下各添加多个包络带。当价格触碰包络带时,根据方向开仓做多或做空。当价格回归到均线时,平仓退出。
该策略使用双指数移动均线(DEMA)作为基础指标。双指数移动均线是一种对价格变化灵敏度较高的移动均线。在其基础上,策略分别在上下两侧添加多个价格带,构成一个均线包络区。包络区的范围由用户设定,每条价格带之间按照一定百分比间隔。
当价格上涨逼近上边包络带时,该策略会开仓做空;当价格下跌触碰下边包络带时,该策略会开仓做多。每碰触一条新的价格带带就会加仓一次。当价格回归移动均线附近时,策略会平仓所有头寸。
该策略通过包络区捕捉价格过激波动,并在反转来临时获利退出,实现低买高卖的交易目标。它适用于有明显均值回归特征的市场周期,如比特币等数字货币。
可以通过适当放宽包络区范围,增加触发价格变化的敏感性来降低风险。同时调整移动均线长度参数,适应不同周期行情。
该策略可以从以下几个方面进行优化:
优化移动均线算法。可以测试不同类型的移动均线指标效果。
调整均线长度参数。缩短周期可以提高对短期价格变化的捕捉,但也可能增加噪声交易。
优化包络区参数。可以测试不同百分比设置,找到最优参数组合。
增加止损策略。设定移动止损或回撤止损,可以有效控制单笔损失。
增加过滤条件。结合其他指标信号,避免非理性行情下无效开仓。
意向反转包络均值策略通过构建均线价格通道,有效捕捉价格反转机会。它可以灵活调整参数,适用于不同市场环境。该策略transaction成本较低,回报率较高,是一种值得推荐的量化交易策略。
/*backtest
start: 2022-11-27 00:00:00
end: 2023-12-03 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy("Mean Reversion - Envelope Strategy", overlay=true )
// ----------------------- DESCRIPTION -----------------------
// THIS SCRIPT IS A MEAN REVERSION SYSTEM THAT USES A MOVING AVERAGE AS BASE CALCULATION AND A % OF THIS MOVING AVERAGE TO CALCULATE THE ENVELOPE
// BY DEFAULT, THE SYSTEM WILL PLACE LONG ORDERS ON THE MOVING AVERAGE -5% PER ENVELOPE COUNT (5%, 10% AND SO ON...)
// YOU CAN ENABLE THE SHORT ORDERS THAT WILL FOLLOW THE SAME LOGIC ON THE OPPOSITE SIDE
// THE SYSTEM WILL CLOSE EVERY ONGOING TRADE WHEN THE PRICE RETURNS TO THE MEAN
// ---------------------------------------------
// ---------------- SETTINGS -------------------
src = input(close, "Moving Average Source", group = "Moving Average")
ma_window = input.int(5, "Moving Average Window", step = 1, group = "Moving Average")
ma_type = input.string('4. DEMA', "Moving Average Type", options=['1. SMA', '2. EMA', '3. RMA', '4. DEMA'], group = "Moving Average")
enveloppe_step = input.float(0.05, "Delta Per Enveloppe", step = 0.01, group = "Envelope")
envelope_count = input.int(5, "Envelope count", options = [1, 2, 3, 4, 5], group = "Envelope")
use_longs = input.bool(true, 'Use Long Orders ?', group = "Orders")
use_short = input.bool(false, 'Use Short Orders ?', group = "Orders")
// ---------------------------------------------
// -------------- INDICATORS -------------------
ma_funct() =>
if(ma_type == '1. SMA')
ta.sma(src, ma_window)
if(ma_type == '2. EMA')
ta.ema(src, ma_window)
if(ma_type == '3. RMA')
ta.rma(src, ma_window)
if(ma_type == '4. DEMA')
2 * ta.ema(src, ma_window) - ta.ema(ta.ema(src, ma_window), ma_window)
ma_base = ma_funct()
ma_high_1 = envelope_count > 0 ? ma_base * (1 + enveloppe_step) : na
ma_high_2 = envelope_count > 1 ? ma_base * (1 + enveloppe_step * 2) : na
ma_high_3 = envelope_count > 2 ? ma_base * (1 + enveloppe_step * 3) : na
ma_high_4 = envelope_count > 3 ? ma_base * (1 + enveloppe_step * 4) : na
ma_high_5 = envelope_count > 4 ? ma_base * (1 + enveloppe_step * 5) : na
ma_low_1 = envelope_count > 0 ? ma_base * (1 - enveloppe_step) : na
ma_low_2 = envelope_count > 0 ? ma_base * (1 - enveloppe_step * 2) : na
ma_low_3 = envelope_count > 0 ? ma_base * (1 - enveloppe_step * 3) : na
ma_low_4 = envelope_count > 0 ? ma_base * (1 - enveloppe_step * 4) : na
ma_low_5 = envelope_count > 0 ? ma_base * (1 - enveloppe_step * 5) : na
// ---------------------------------------------
// --------------- STRATEGY --------------------
if use_longs
if envelope_count > 0 and strategy.opentrades < 1
strategy.entry('long 1', strategy.long, limit=ma_low_1, qty=(strategy.equity / ma_low_1) * (1 / envelope_count))
if envelope_count > 1 and strategy.opentrades < 2
strategy.entry('long 2', strategy.long, limit=ma_low_2, qty=(strategy.equity / ma_low_2) * (1 / envelope_count))
if envelope_count > 2 and strategy.opentrades < 3
strategy.entry('long 3', strategy.long, limit=ma_low_3, qty=(strategy.equity / ma_low_3) * (1 / envelope_count))
if envelope_count > 3 and strategy.opentrades < 4
strategy.entry('long 4', strategy.long, limit=ma_low_4, qty=(strategy.equity / ma_low_4) * (1 / envelope_count))
if envelope_count > 4 and strategy.opentrades < 5
strategy.entry('long 5', strategy.long, limit=ma_low_5, qty=(strategy.equity / ma_low_5) * (1 / envelope_count))
if use_short
if envelope_count > 0 and strategy.opentrades < 1
strategy.entry('short 1', strategy.short, limit=ma_high_1, qty=(strategy.equity / ma_high_1) * (1 / envelope_count))
if envelope_count > 1 and strategy.opentrades < 2
strategy.entry('short 2', strategy.short, limit=ma_high_2, qty=(strategy.equity / ma_high_2) * (1 / envelope_count))
if envelope_count > 2 and strategy.opentrades < 3
strategy.entry('short 3', strategy.short, limit=ma_high_3, qty=(strategy.equity / ma_high_3) * (1 / envelope_count))
if envelope_count > 3 and strategy.opentrades < 4
strategy.entry('short 4', strategy.short, limit=ma_high_4, qty=(strategy.equity / ma_high_4) * (1 / envelope_count))
if envelope_count > 4 and strategy.opentrades < 5
strategy.entry('short 5', strategy.short, limit=ma_high_5, qty=(strategy.equity / ma_high_5) * (1 / envelope_count))
strategy.exit('close', limit=ma_base)
// ---------------------------------------------
// ------------------ PLOT ---------------------
ma_base_plot = plot(ma_base, title = "Base MA", color = color.orange, linewidth = 3, offset = 1)
ma_high_1_plot = plot(ma_high_1, title = "MA high 1", color = color.red, offset = 1)
ma_high_2_plot = plot(ma_high_2, title = "MA high 2", color = color.red, offset = 1)
ma_high_3_plot = plot(ma_high_3, title = "MA high 3", color = color.red, offset = 1)
ma_high_4_plot = plot(ma_high_4, title = "MA high 4", color = color.red, offset = 1)
ma_high_5_plot = plot(ma_high_5, title = "MA high 5", color = color.red, offset = 1)
ma_low_1_plot = plot(ma_low_1, title = "MA low 1", color = color.green, offset = 1)
ma_low_2_plot = plot(ma_low_2, title = "MA low 2", color = color.green, offset = 1)
ma_low_3_plot = plot(ma_low_3, title = "MA low 3", color = color.green, offset = 1)
ma_low_4_plot = plot(ma_low_4, title = "MA low 4", color = color.green, offset = 1)
ma_low_5_plot = plot(ma_low_5, title = "MA low 5", color = color.green, offset = 1)