该策略结合MACD动量指标和RSI超买超卖指标,在MACD发生金叉/死叉时验证RSI是否也完成了对应的触底/触顶回转,从而产生更可靠的交易信号。属于典型的短期反转策略思路。
计算MACD指标的DIFF、DEA和MACD柱。当DIFF上穿DEA时产生金叉信号,下穿时死叉信号。
计算RSI指标,判断是否触底反弹或触顶回落。并设置回看窗口判断最近阶段是否出现过触底或触顶。
当MACD金叉时,如果RSI在回看窗口内完成了触底反弹,则产生看多信号。当MACD死叉时,如果RSI完成了触顶回落,则看空信号。
入场后设置止损点以控制风险。
MACD判断趋势转折时机灵敏。RSI判断超买超卖状况有效。
同时验证MACD和RSI令牌,可过滤假信号。
回看窗口判断增加信号的可靠性。
设置止损有助于风险管理。
MACD和RSI均存在一定滞后,可能错过最优入场点。
同时等待两指标信号出现的概率较小,信号较少。
没有考虑大级别趋势方向,容易被套。
止损设置不当可能过于宽松或严格。
对应解决方法:
调整MACD和RSI参数,降低滞后概率。
适当扩大指标的有效区间,提供更多信号。
增加趋势过滤,避免逆势入场。
测试不同的止损参数设置,找到最优点。
测试SMA等其他均线的效果。
增加移动止损,让止损更灵活。
添加趋势力指标,判断入场的优劣。
引入机器学习预测指标走势。
结合更多因子优化入场时机选择。
该策略利用MACD和RSI两个指标的配合,在筛选出可靠的反转信号后入场。策略思路清晰、参数调整灵活,可从指标选择、趋势判断、止损方式等方面进行扩展,在保持稳定的基础上获取更多交易机会。但需要注意防止由于过度优化而丧失稳健性。
/*backtest
start: 2023-08-24 00:00:00
end: 2023-09-23 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
//based on Range Strat - MACD/RSI
// strategy("MACD/RSI - edited",
// overlay=true,
// default_qty_type=strategy.percent_of_equity,
// default_qty_value=10, precision=2, initial_capital=100000,
// pyramiding=2,
// commission_value=0.05)
//Backtest date range
StartDate = input(timestamp("13 Jun 2022"), title="Start Date")
EndDate = input(timestamp("13 Jun 2024"), title="Start Date")
inDateRange = true
// RSI Input Settings
rsisrc = input(title="RSI Source", defval=close, group="RSI Settings")
length = input(title="Length", defval=14, group="RSI Settings" )
overSold = input(title="Over Sold Threshold", defval=30, group="RSI Settings" )
overBought = input(title="Over Bought Threshold", defval=70, group="RSI Settings" )
rsi_lookback = input(title="RSI cross lookback period", defval=7, group="RSI Settings")
// Calculating RSI
vrsi = ta.rsi(rsisrc, length)
co = ta.crossover(vrsi, overSold)
cu = ta.crossunder(vrsi, overBought)
// Function looking for a happened condition during lookback period
f_somethingHappened(_cond, _lookback) =>
bool _crossed = false
for i = 1 to _lookback
if _cond[i]
_crossed := true
_crossed
coCheck = f_somethingHappened(co, rsi_lookback)
cuCheck = f_somethingHappened(cu, rsi_lookback)
// MACD Input Settings
macdsrc = input(title="MACD Source", defval=close, group="MACD Settings")
fast_length = input(title="Fast Length", defval=12, group="MACD Settings")
slow_length = input(title="Slow Length", defval=26, group="MACD Settings")
signal_length = input.int(title="Signal Smoothing", minval = 1, maxval = 50, defval = 9, group="MACD Settings")
sma_source = input.string(title="Oscillator MA Type", defval="EMA", options=["SMA", "EMA"], group="MACD Settings")
sma_signal = input.string(title="Signal Line MA Type", defval="EMA", options=["SMA", "EMA"], group="MACD Settings")
// Calculating MACD
fast_ma = sma_source == "SMA" ? ta.sma(macdsrc, fast_length) : ta.ema(macdsrc, fast_length)
slow_ma = sma_source == "SMA" ? ta.sma(macdsrc, slow_length) : ta.ema(macdsrc, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal == "SMA" ? ta.sma(macd, signal_length) : ta.ema(macd, signal_length)
delta = macd - signal
MACDcrossover = ta.crossover(delta, 0)
MACDcrossunder = ta.crossunder(delta, 0)
// Stop Loss Input Settings
longLossPerc = input(title="Long Stop Loss (%)", defval=15, group="Stop Loss Settings") * 0.01
shortLossPerc = input(title="Short Stop Loss (%)", defval=15, group="Stop Loss Settings") * 0.01
// Calculating Stop Loss
longStopPrice = strategy.position_avg_price * (1 - longLossPerc)
shortStopPrice = strategy.position_avg_price * (1 + shortLossPerc)
// Strategy Entry
if (not na(vrsi))
if (inDateRange and MACDcrossover and coCheck)
strategy.entry("LONG", strategy.long, comment="LONG")
if (inDateRange and MACDcrossunder and cuCheck)
strategy.entry("SHORT", strategy.short, comment="SHORT")
// Submit exit orders based on calculated stop loss price
if (strategy.position_size > 0)
strategy.exit(id="LONG STOP", stop=longStopPrice)
if (strategy.position_size < 0)
strategy.exit(id="SHORT STOP", stop=shortStopPrice)