策略知识库.EN
策略

基于Uhl-MA的自适应均线交叉策略Adaptive-Moving-Average-Crossover-Strategy-Based-on-Uhl-MA

ChaoZhang · PineScript · 波动率与通道 · 2023-09-19 22:06:42

全部策略 →
过滤
仓位
—
风控
出场
—

概述

Uhl MA系统是一个自适应的均线交叉系统,其设计目的是为了弥补传统均线系统的不足。该系统采用快速均线和慢速均线交叉产生交易信号。慢速均线采用Uhl最初提出的修正均线(CMA),快速均线采用也基于修正均线思想的修正趋势步(CTS)。系统通过自适应调整均线参数,实现更稳定可靠的交易信号。

优势

相比传统均线交叉系统,该策略最大的优势是采用自适应均线,可以过滤部分噪声,在震荡行情中产生更可靠的交易信号。相比死叉金叉,自适应均线交叉减少了误交易的概率。另外,快线慢线配合,可以抓住较好的趋势交易机会。从回测结果看,在趋势明显的品种中,策略表现优异。

风险

由于均线本质上是用来判断趋势的技术指标,该策略最大的风险在于震荡行情下产生错误信号的概率较大。这主要源自CMA均线的自适应计算方法,在震荡行情中也会收敛到价格区域,产生不必要的信号。另外,寻找合适的参数组合也是一大难题。如果参数设置不当,会错过较好的交易机会或者增大错误信号概率。

总结

Uhl MA系统是一个非常有创新思维的自适应均线交叉策略。相比传统策略,其采用动态均线可以减少误交易的概率,更好的捕捉趋势机会。但该策略也存在一定局限性,主要在震荡行情下的表现不佳。通过进一步改进计算方法,引入其他辅助指标进行过滤优化,仍有非常大的提升空间。与此同时,参数优化和风险控制也是关键。总体来说,Uhl MA策略具有较好的发展前景和研究价值。 [/trans]

其他

该策略的核心是Uhl MA均线和CTS均线的计算。其中,Uhl MA均线是在传统SMA均线的基础上进行修正,通过引入方差VAR和历史CMA的平方差SECMA进行自适应调整。当VAR小于SECMA时,增加SMA占比;当VAR大于SECMA时,增加CMA的占比。这样可以过滤掉部分噪声,产生更稳定的均线。CTS均线与Uhl MA均线计算思路类似,是在SRC价格的基础上进行自适应调整。 交叉原理与传统均线交叉系统相同,当CTS向上穿过Uhl MA时产生买入信号,当CTS向下穿过Uhl MA时产生卖出信号。这样就构成一个自适应的均线交易系统。 该策略主要可以从以下几个方面进行优化:

  1. 改进CMA自适应计算方法,避免其在震荡行情中收敛,产生错误信号。可以考虑引入别的指标进行修正。
  2. 优化参数设定,寻找最佳的参数组合。可以通过遗传算法等方法进行多维参数优化。
  3. 增加止损策略,以控制单笔损失。
  4. 结合其他指标过滤信号,避免在震荡行情中频繁交易。比如引入波动率指标、RFM指标等。
  5. 优化资金管理,例如风险度量、仓位控制等,更好的控制整体风险。

参数

参数默认值说明
v_input_1100length
v_input_2truemult
v_input_3_close0src: close
源码(35 行)
/*backtest
start: 2023-01-01 00:00:00
end: 2023-06-25 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © alexgrover

//@version=4
strategy("Uhl MA System - Strategy Analysis")
length = input(100),mult = input(1.),src = input(close)
//----
out = 0., cma = 0., cts = 0.
Var = variance(src,length)           ,sma = sma(src,length)
secma = pow(nz(sma - cma[1]),2)      ,sects = pow(nz(src - cts[1]),2) 
ka = Var < secma ? 1 - Var/secma : 0 ,kb = Var < sects ? 1 - Var/sects : 0
cma := ka*sma+(1-ka)*nz(cma[1],src)  ,cts := kb*src+(1-kb)*nz(cts[1],src)
//----
if crossover(cts,cma)
    strategy.entry("Buy", strategy.long)
if crossunder(cts,cma)
    strategy.entry("Sell", strategy.short)
//----
cap = 50000
eq = strategy.equity
rmax = 0.
rmax := max(eq,nz(rmax[1]))
//----
css = eq > cap ? #0cb51a : #e65100
a = plot(eq,"Equity",#2196f3,2,transp=0)
b = plot(rmax,"Maximum",css,2,transp=0)
fill(a,b,css,80)