移动平均与相对强弱指标策略


创建日期: 2023-11-28 14:07:46 最后修改: 2023-11-28 14:07:46
复制: 0 点击次数: 521
avatar of ChaoZhang ChaoZhang
1
关注
1359
关注者

移动平均与相对强弱指标策略

概述

移动平均与相对强弱指标策略(Moving Average Relative Strength Index Strategy)是一种同时利用移动平均线和相对强弱指标作为交易信号的量化交易策略。该策略通过比较价格的移动平均线和相对强弱指标的数值,产生交易信号,以捕捉市场趋势中的机会。

策略原理

该策略主要基于两个指标:

  1. 简单移动平均线(SMA):反映价格的平均趋势。
  2. 相对强弱指标(RSI):反映价格的强弱态势。

策略的核心逻辑是:

当RSI指标线低于移动平均线时为超卖区域,视为股票被低估,产生买入信号;当RSI指标线高于移动平均线时为超买区域,视为股票被高估,产生卖出信号。

也就是说,移动平均线在一定程度上反映股票的公允价值,RSI指标代表股票目前的强弱态势。RSI指标高于或低于移动平均线,意味着存在反转的机会。

具体来说,该策略通过以下步骤产生交易信号:

  1. 计算股票的RSI指标值,以及简单移动平均线
  2. 比较RSI指标值与移动平均线的大小关系
  3. 当RSI指标上穿移动平均线时,产生卖出信号
  4. 当RSI指标下穿移动平均线时,产生买入信号
  5. 设置止损点和移动止损来控制风险

策略优势

该策略结合移动平均线的趋势判断和RSI指标的超买超卖判断,综合利用不同指标的优势,可以有效判断市场的转折点。

主要优势有:

  1. 移动平均线能够有效地指示价格趋势
  2. RSI指标可以反映超买超卖现象
  3. 结合双重指标,判断市场转折点的准确性更高
  4. 可以设置止损点来控制风险

策略风险

该策略也存在一些风险:

  1. 指标产生错误信号的概率存在,可能导致不必要的亏损
  2. 行情剧烈震荡时,止损可能被突破,造成较大亏损
  3. 参数设置不当也会影响策略表现

为了控制风险,可以通过以下方式进行优化:

  1. 调整移动平均线和RSI的参数,使指标信号更可靠
  2. 适当宽松止损点,避免止损过于频繁被触发
  3. 采用移动止损DYNAMIC止损等方式,使止损更加灵活

策略优化方向

该策略还可进一步优化的方向包括:

  1. 测试不同周期的参数组合,寻找最佳参数
  2. 增加其他指标过滤,如成交量指标等,提高信号的可靠性
  3. 优化止损策略,使止损更加动态和合理
  4. 结合深度学习等技术,建立自适应参数优化机制
  5. 增加仓位管理模块,根据市场情况动态调整仓位

通过参数优化、指标优化、风险管理优化等方式,可以不断提升该策略的稳定性和盈利能力。

总结

移动平均与相对强弱指标策略同时利用价格趋势判断和超买超卖判断,可以有效判断市场转折点,抓住反转机会。该策略简单实用,风险可控,是一种实用的量化交易策略。通过持续优化,可以获得更加出色的效果。

策略源码
/*backtest
start: 2023-11-20 00:00:00
end: 2023-11-24 06:00:00
period: 10m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=2

strategy(title = "RSI versus SMA", shorttitle = "RSI vs SMA", overlay = false, pyramiding = 0, default_qty_type = strategy.percent_of_equity, default_qty_value = 10, currency = currency.GBP)

// Revision:        1
// Author:          @JayRogers
//
// *** USE AT YOUR OWN RISK ***
// - Nothing is perfect, and all decisions by you are on your own head. And stuff.
//
// Description:
//  - It's RSI versus a Simple Moving Average.. Not sure it really needs much more description.
//  - Should not repaint - Automatically offsets by 1 bar if anything other than "open" selected as RSI source.

// === INPUTS ===
// rsi
rsiSource   = input(defval = open, title = "RSI Source")
rsiLength   = input(defval = 8, title = "RSI Length", minval = 1)
// sma
maLength    = input(defval = 34, title = "MA Period", minval = 1)
// invert trade direction
tradeInvert = input(defval = false, title = "Invert Trade Direction?")
// risk management
useStop     = input(defval = false, title = "Use Initial Stop Loss?")
slPoints    = input(defval = 25, title = "Initial Stop Loss Points", minval = 1)
useTS       = input(defval = true, title = "Use Trailing Stop?")
tslPoints   = input(defval = 120, title = "Trail Points", minval = 1)
useTSO      = input(defval = false, title = "Use Offset For Trailing Stop?")
tslOffset   = input(defval = 20, title = "Trail Offset Points", minval = 1)
// === /INPUTS ===

// === BASE FUNCTIONS ===
// delay for direction change actions
switchDelay(exp, len) =>
    average = len >= 2 ? sum(exp, len) / len : exp[1]
    up      = exp > average
    down    = exp < average
    state   = up ? true : down ? false : up[1]
// === /BASE FUNCTIONS ===

// === SERIES and VAR ===
// rsi
shunt = rsiSource == open ? 0 : 1
rsiUp = rma(max(change(rsiSource[shunt]), 0), rsiLength)
rsiDown = rma(-min(change(rsiSource[shunt]), 0), rsiLength)
rsi = (rsiDown == 0 ? 100 : rsiUp == 0 ? 0 : 100 - (100 / (1 + rsiUp / rsiDown))) - 50 // shifted 50 points to make 0 median
// sma of rsi
rsiMa   = sma(rsi, maLength)
// self explanatory..
tradeDirection = tradeInvert ? 0 <= rsiMa ? true : false : 0 >= rsiMa ? true : false
// === /SERIES ===

// === PLOTTING ===
barcolor(color = tradeDirection ? green : red, title = "Bar Colours")
// hlines
medianLine  = hline(0, title = 'Median', color = #996600,  linewidth = 1)
limitUp     = hline(25, title = 'Limit Up', color = silver,  linewidth = 1)
limitDown   = hline(-25, title = 'Limit Down', color = silver,  linewidth = 1)
// rsi and ma
rsiLine     = plot(rsi, title = 'RSI', color = purple, linewidth = 2, style = line, transp = 50)
areaLine    = plot(rsiMa, title = 'Area MA', color = silver, linewidth = 1, style = area, transp = 70)
// === /PLOTTING ===

goLong() => not tradeDirection[1] and tradeDirection
killLong() => tradeDirection[1] and not tradeDirection
strategy.entry(id = "Buy", long = true, when = goLong())
strategy.close(id = "Buy", when = killLong())

goShort() => tradeDirection[1] and not tradeDirection
killShort() => not tradeDirection[1] and tradeDirection
strategy.entry(id = "Sell", long = false, when = goShort())
strategy.close(id = "Sell", when = killShort())

if (useStop)
    strategy.exit("XSL", from_entry = "Buy", loss = slPoints)
    strategy.exit("XSS", from_entry = "Sell", loss = slPoints)
// if we're using the trailing stop
if (useTS and useTSO) // with offset
    strategy.exit("XSL", from_entry = "Buy", trail_points = tslPoints, trail_offset = tslOffset)
    strategy.exit("XSS", from_entry = "Sell", trail_points = tslPoints, trail_offset = tslOffset)
if (useTS and not useTSO) // without offset
    strategy.exit("XSL", from_entry = "Buy", trail_points = tslPoints)
    strategy.exit("XSS", from_entry = "Sell", trail_points = tslPoints)