动量震荡策略是一种结合随机动量指标和相对强弱指标的量化交易策略。该策略运用随机动量指标判断市场超买超卖区域,配合快速RSI指标过滤信号,再通过实体过滤实现更可靠的交易信号选择。
随机动量指数(SMI)是一种量化交易中常用的技术指标,它结合了动量指标和震荡指标的优点。
具体来说,SMI的计算公式为:
SMI = (Close - (HH + LL)/2)/(0.5*(HH - LL)) * 100
其中,HH是过去N天的最高价,LL是过去N天的最低价。
这样,SMI结合了动量的趋势判断和震荡的反转判断。当SMI高于80时为超买,低于20时为超卖。策略会在超买超卖区域发出交易信号。
相对强弱指数(RSI)是一种常用的超买超卖指标。该策略中使用周期为7的快速RSI,来判断短期内的超买超卖状况。
当快速RSI低于20时为超卖,高于80时为超买。策略会在超买超卖区域发出交易信号。
该策略还加入了实体过滤器,通过计算K线实体的大小,来过滤部分信号。只有当K线实体超过一定阈值时,才会发出交易信号。
这可以过滤掉一些假信号,提高信号的可靠性。
该策略结合了随机动量指标、快速RSI指标和实体过滤器三个部分。通过多指标联立,可以提高信号准确率,增强策略稳健性。
随机动量指标和快速RSI指标都能准确判断市场的超买超卖状态,策略在超买超卖区域开仓,遵循买入低位、卖出高位的交易原则。
策略可进行多头和空头双向交易,最大限度捕捉市场上的交易机会。
实体过滤器的加入,可以过滤掉大部分噪音,避免在震荡行情中被套。
策略进行双向交易,多空头频繁切换是一个潜在的风险点。适当优化开仓逻辑可以降低此风险。
指标给出信号时,可能会在短时间内聚集大量跟风交易者,导致行情反转风险。可以通过优化指标参数降低此风险。
极端行情下,所有模型都可能失效。这需要通过合理设置止损来控制此类风险。
可以通过测试不同的参数组合,如SMI周期、RSI周期、实体过滤器阈值等,寻找最佳参数以提高策略收益率。
建立基于ATR或波动率的动态止损机制,可以更好地控制个股和整体的风险。
引入机器学习算法,通过模型预测指标值的未来走势。这可以提前判断指标的转折点,增强策略的前瞻性。
综上所述,该策略整合随机动量指标、快速RSI指标和实体过滤器,实现了一套较为完整的超买超卖判断体系。多指标组合提高了信号准确性,双向交易和风险控制机制也使策略更加平衡。通过持续优化参数和模型,该策略有望获取较好的收益率。
/*backtest
start: 2023-12-22 00:00:00
end: 2024-01-21 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//Noro
//2018
//@version=2
strategy(title = "Noro's Stochastic Strategy v1.1", shorttitle = "Stochastic str 1.1", overlay = false, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, pyramiding = 0)
//Settings
needlong = input(true, defval = true, title = "Long")
needshort = input(true, defval = true, title = "Short")
usemar = input(false, defval = false, title = "Use Martingale")
capital = input(100, defval = 100, minval = 1, maxval = 10000, title = "Capital, %")
usesmi = input(true, defval = true, title = "Use SMI Strategy")
usersi = input(true, defval = true, title = "Use RSI Strategy")
usebod = input(true, defval = true, title = "Use Body-Filter")
a = input(5, "SMI Percent K Length")
b = input(3, "SMI Percent D Length")
limit = input(50, defval = 50, minval = 1, maxval = 100, title = "SMI Limit")
fromyear = input(2017, defval = 2017, minval = 1900, maxval = 2100, title = "From Year")
toyear = input(2100, defval = 2100, minval = 1900, maxval = 2100, title = "To Year")
frommonth = input(01, defval = 01, minval = 01, maxval = 12, title = "From Month")
tomonth = input(12, defval = 12, minval = 01, maxval = 12, title = "To Month")
fromday = input(01, defval = 01, minval = 01, maxval = 31, title = "From day")
today = input(31, defval = 31, minval = 01, maxval = 31, title = "To day")
//Fast RSI
fastup = rma(max(change(close), 0), 7)
fastdown = rma(-min(change(close), 0), 7)
fastrsi = fastdown == 0 ? 100 : fastup == 0 ? 0 : 100 - (100 / (1 + fastup / fastdown))
//Stochastic Momentum Index
ll = lowest (low, a)
hh = highest (high, a)
diff = hh - ll
rdiff = close - (hh+ll)/2
avgrel = ema(ema(rdiff,b),b)
avgdiff = ema(ema(diff,b),b)
SMI = avgdiff != 0 ? (avgrel/(avgdiff/2)*100) : 0
SMIsignal = ema(SMI,b)
//Lines
plot(SMI, color = blue, linewidth = 3, title = "Stochastic Momentum Index")
plot(SMIsignal, color = red, linewidth = 3, title = "SMI Signal Line")
plot(limit, color = black, title = "Over Bought")
plot(-1 * limit, color = black, title = "Over Sold")
plot(0, color = blue, title = "Zero Line")
//Body Filter
nbody = abs(close - open)
abody = sma(nbody, 10)
body = nbody > abody / 3 or usebod == false
//Signals
up1 = SMIsignal < -1 * limit and close < open and body and usesmi
dn1 = SMIsignal > limit and close > open and body and usesmi
up2 = fastrsi < 20 and close < open and body and usersi
dn2 = fastrsi > 80 and close > open and body and usersi
exit = ((strategy.position_size > 0 and close > open) or (strategy.position_size < 0 and close < open)) and body
//Trading
profit = exit ? ((strategy.position_size > 0 and close > strategy.position_avg_price) or (strategy.position_size < 0 and close < strategy.position_avg_price)) ? 1 : -1 : profit[1]
mult = usemar ? exit ? profit == -1 ? mult[1] * 2 : 1 : mult[1] : 1
lot = strategy.position_size == 0 ? strategy.equity / close * capital / 100 * mult : lot[1]
if up1 or up2
if strategy.position_size < 0
strategy.close_all()
strategy.entry("long", strategy.long, needlong == false ? 0 : lot, when=(time > timestamp(fromyear, frommonth, fromday, 00, 00) and time < timestamp(toyear, tomonth, today, 23, 59)))
if dn1 or dn2
if strategy.position_size > 0
strategy.close_all()
strategy.entry("Short", strategy.short, needshort == false ? 0 : lot, when=(time > timestamp(fromyear, frommonth, fromday, 00, 00) and time < timestamp(toyear, tomonth, today, 23, 59)))
if time > timestamp(toyear, tomonth, today, 23, 59) or exit
strategy.close_all()