该策略通过Jurik移动平均线(JMA)与RSI指标的交叉来产生买卖信号。当JMA上穿RSI时做多,当JMA下穿RSI时做空。该策略试图利用两个指标的组合过滤假信号,在趋势较明显时进行交易。
该策略主要利用两种指标进行组合:
JMA指标:一种用幂乘数平滑移动平均线,具有更低的滞后性,能更快捕捉价格变化。
RSI指标:较为常见的强弱指标,反映市场买卖力道。
当JMA上穿RSI时,表示短期价格上涨势头强于长期趋势,产生买入信号;当JMA下穿RSI时,提示做空信号。
交叉信号发出后,交易在对应方向开仓。平仓条件为价格超过指定目标比例或指标再次交叉反向。
JMA指标参数可调,能够对不同周期进行优化。
RSI指标可过滤假突破。
采用双指标组合,可减少假信号。
内置止损机制,可以限制亏损。
可自定义盈利比例,实现盈利目标。
双指标组合inating,信号产生频率可能过低。可调整参数,使指标更敏感。
JMA指标还存在滞后问题,可能错过价格转折点。可结合其他先导指标进行优化。
止损点设置不当可能被突破导致亏损扩大。应根据历史数据测试确定适合的止损位。
仅依赖指标易产生假信号。可加入交易量或波动率指标进行过滤。
对JMA参数进行测试,找到最佳参数组合。
尝试不同的RSI参数Setting,优化指标效果。
加入移动止损机制,让止损更具适应性。
优化开仓仓位管理逻辑,如加入加仓和分批建仓条件。
研究其他指标Filter信号,如KD、MACD等。
该策略基于JMA和RSI两个指标交叉实现趋势跟踪,可配置止损来限制风险。但仍存在一定假信号概率,需要继续优化指标参数和过滤条件来减少失误交易。止损策略也需要根据回测数据进行优化测试。本策略为双指标交叉交易提供了基础框架,具有一定的拓展空间。
/*backtest
start: 2023-01-01 00:00:00
end: 2023-03-15 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=4
// Stratégie marche le mieux sur du 2 jours
strategy("JMA(7,50,RSI) crossing RSI(14,close)", overlay=false, currency=currency.EUR, default_qty_type=strategy.cash, default_qty_value=5000)
// Strategy Tester Start Time
sYear = input(2019, title = "Start Year")
sMonth = input(06, title = "Start Month", minval = 01, maxval = 12)
sDay = input(01, title = "Start Day", minval = 01, maxval = 31)
sHour = input(00, title = "Start Hour", minval = 00, maxval = 23)
sMinute = input(00, title = "Start Minute", minval = 00, maxval = 59)
startTime = true
// Strategy Tester End Time
eYear = input(2019, title = "End Year")
eMonth = input(12, title = "End Month", minval = 01, maxval = 12)
eDay = input(01, title = "End Day", minval = 01, maxval = 31)
eHour = input(00, title = "End Hour", minval = 00, maxval = 23)
eMinute = input(00, title = "End Minute", minval = 00, maxval = 59)
endTime = true
// === RSI ===
src = close, len = input(14, minval=1, title="Length")
up = rma(max(change(src), 0), len)
down = rma(-min(change(src), 0), len)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
plot(rsi, color=color.purple)
band1 = hline(70)
band0 = hline(30)
// === JMA ===
_length = input(7, title="Length")
_phase = input(50, title="Phase")
_power = input(2, title="Power")
highlightMovements = input(true, title="Highlight Movements ?")
// srcJMA = input(rsi, title="Source")
srcJMA = rsi
phaseRatio = _phase < -100 ? 0.5 : _phase > 100 ? 2.5 : _phase / 100 + 1.5
beta = 0.45 * (_length - 1) / (0.45 * (_length - 1) + 2)
alpha = pow(beta, _power)
jma = 0.0
e0 = 0.0
e0 := (1 - alpha) * srcJMA + alpha * nz(e0[1])
e1 = 0.0
e1 := (srcJMA - e0) * (1 - beta) + beta * nz(e1[1])
e2 = 0.0
e2 := (e0 + phaseRatio * e1 - nz(jma[1])) * pow(1 - alpha, 2) + pow(alpha, 2) * nz(e2[1])
jma := e2 + nz(jma[1])
// === End of JMA def ===
jmaColor = highlightMovements ? (jma > jma[1] ? color.green : color.red) : #6d1e7f
plot(jma, title="JMA switch", linewidth=2, color=jmaColor, transp=0)
// === Inputs ===
// risk management
useStop = input(true, title = "Use Initial Stop Loss?")
goLong() => crossover(rsi, jma)
killLong() => crossunder(rsi, jma)
// ======= DEBUGGGGGGGG ============
long_price = 0.0
short_price = 0.0
if(startTime and endTime)
if(goLong())
long_price := close
strategy.entry("Buy", strategy.long, when = goLong())
strategy.close("Buy", when = killLong() and close > long_price)
// Shorting if using
goShort() => killLong()
killShort() => goLong()
if(startTime and endTime)
if(goShort())
short_price := close
strategy.entry("Sell", strategy.short, when = goShort() and close < short_price)
strategy.close("Sell", when = killShort())
// =========================
if (useStop)
strategy.exit("XLS", from_entry ="Buy", stop = strategy.position_avg_price / 1.08)
strategy.exit("XSS", from_entry ="Sell", stop = strategy.position_avg_price * 1.08)