个性化动量交易策略


创建日期: 2023-11-23 15:18:27 最后修改: 2023-11-23 15:18:27
复制: 0 点击次数: 518
avatar of ChaoZhang ChaoZhang
1
关注
1370
关注者

个性化动量交易策略

概述

这是一个结合了动量指标和K线实体过滤的个性化交易策略。它综合运用了随机动量指数、快速RSI和K线实体过滤三种技术指标,实现了一个动量突破为主,同时考虑超买超卖的策略。

策略原理

本策略使用以下三个指标进行交易信号判断:

  1. 随机动量指数(SMI):它结合了K线实体间距和收盘价的相对位置,判断价格动能强弱。当SMI上穿过界线时产生买入信号,下穿界线时产生卖出信号。

  2. 快速RSI(7日线):它判断了价格的超买超卖状况。RSI低于20时为超卖产生买入信号,高于80时为超买产生卖出信号。

  3. K线实体过滤:计算10日内的平均K线实体大小,当今日K线实体超过该平均值的三分之一时有效,避免无效信号。

本策略首先判断SMI和RSI的信号,如果符合其中一个indicator的信号要求,再结合K线实体过滤判定该信号是否有效,如果有效则产生交易信号。

优势分析

本策略具有以下优势:

  1. 多个指标结合,判断更精确可靠。

  2. 增加K线实体过滤,避免无效信号。

  3. 结合超买超卖判断,在趋势反转点更容易捕捉信号。

  4. 多空两个方向交易,收益机会增加。

  5. 采用部分交易仓位,避免单次交易过度损失。

风险分析

本策略也存在一些风险:

  1. 指标作用下,容易产生误信号导致亏损。可通过参数优化减少误信号。

  2. 部分仓位交易无法充分利用每个方向的趋势机会。可通过放大交易仓位获得更高收益。

  3. SMI作为主指标,对参数设置敏感,不当设置可能错过交易机会或增加误信号。

  4. 多空双向交易,操作频繁,交易成本增加。

优化方向

本策略可从以下几个方向进行进一步优化:

  1. 优化SMI和RSI的参数,找到最佳参数组合。

  2. 增加仓位放大和仓位管理机制,在趋势中获得更高收益。

  3. 增加止损策略,降低单次亏损风险。

  4. 结合更多indicator判断信号可靠性,减少误信号。

  5. 采用高效合约,降低交易成本。

总结

本策略综合运用了SMI、快速RSI和K线实体过滤三种技术指标,实现了一个动量为主,兼顾超买超卖的个性化交易策略。它具有判断精确、识别有效信号、结合超买超卖和多空交易等优势,也存在一些参数敏感性、不能充分利用趋势、操作频繁等风险。通过持续优化参数设置、增加仓位和止损管理、减少误信号等方法,本策略可以获得更好的交易效果。

策略源码
/*backtest
start: 2023-10-23 00:00:00
end: 2023-11-22 00:00:00
period: 6h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//Noro
//2018

//@version=2
strategy(title = "Noro's Stochastic Strategy v1.2", shorttitle = "Stochastic str 1.2", 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 = SMI < -1 * limit and close < open and body and usesmi
dn1 = SMI > 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()