8.5 KiB
Name
自适应零滞后EMA交易策略Adaptive-Zero-Lag-EMA-Trading-Strategy
Author
ChaoZhang
Strategy Description
[trans]
本策略利用自适应零滞后EMA指标进行趋势判断和交易信号产生。该EMA指标可动态调整参数,有效消除滞后问题。属于典型的趋势跟踪交易策略。
策略原理:
-
计算自适应零滞后EMA指标,包含余弦法和I-Q法两种自适应算法。
-
EMA为正常EMA指标,EC为自适应零滞后EMA。
-
当EC上穿EMA时做多,EC下穿EMA时做空。
-
计算误差曲线,设定阈值过滤假信号。
-
设置固定止损止盈点数,以锁定收益和控制风险。
该策略的优势:
-
自适应EMA可有效减小指标滞后。
-
阈值过滤提高信号质量,避免假突破。
-
止损止盈方式简单实用,易于操作。
该策略的风险:
-
自适应EMA参数不稳定,存在失效的可能。
-
固定止损止盈难以适应市场的变化。
-
无法限制单笔亏损大小,存在较大损失风险。
总之,该策略采用自适应EMA指标进行趋势跟踪,可在一定程度上减小滞后问题,但需要关注参数稳定性,并配合优化的止损止盈机制以控制风险。
||
This strategy uses the Adaptive Zero Lag EMA indicator for trend determination and trade signals. The adaptive EMA dynamically tunes parameters to eliminate lag. It aims for trend following.
Strategy Logic:
-
Calculate Adaptive Zero Lag EMA with cosine and I-Q adaptive algorithms.
-
EMA is normal EMA, EC is adaptive zero lag EMA.
-
Go long when EC crosses above EMA, and short when crossing below.
-
Compute error curve and set threshold to filter false signals.
-
Use fixed points for stop loss and take profit for risk control.
Advantages:
-
Adaptive EMA significantly reduces indicator lag.
-
Threshold filtering improves signal quality and avoids false breakouts.
-
Simple stops and targets are easy to implement.
Risks:
-
Adaptive EMA parameters can become unstable.
-
Fixed stops/targets fail to adapt to changing market conditions.
-
No limit on loss size, risks large losing trades.
In summary, this strategy uses adaptive EMA for trend following, reducing lag to some extent. But parameter stability and optimized stops are needed to control risks.
[/trans]
Strategy Arguments
| Argument | Default | Description |
|---|---|---|
| v_input_1_close | 0 | Source: close |
| v_input_2 | 0 | Security Type: Forex |
| v_input_3 | true | Custom # of Contracts |
| v_input_4 | 100 | Max Lots |
| v_input_5 | 20 | Period |
| v_input_6 | 0 | Adaptive Method: Cos IFM |
| v_input_7 | 8 | Gain Limit |
| v_input_8 | 0.05 | Threshold |
| v_input_9 | 70 | SL Points |
| v_input_10 | 10 | TP Points |
| v_input_11 | 0.01 | Risk |
| v_input_12 | true | From Month |
| v_input_13 | true | From Day |
| v_input_14 | 2019 | From Year |
| v_input_15 | true | To Month |
| v_input_16 | true | To Day |
| v_input_17 | 9999 | To Year |
Source (PineScript)
/*backtest
start: 2023-09-05 00:00:00
end: 2023-09-12 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=3
strategy(title="Adaptive Zero Lag EMA v2 (w/ Backtest Date Range)", shorttitle="AZLEMA", overlay = true, commission_type=strategy.commission.cash_per_contract, slippage = 5, pyramiding=1, calc_on_every_tick=true)
src = input(title="Source", defval=close)
secType = input(title="Security Type", options=["Forex", "Metal Spot", "Cryptocurrency","Custom"], defval="Forex")
contracts = input(title="Custom # of Contracts", defval=1, step=1)
limit = input(title="Max Lots", defval=100)
Period = input(title="Period", defval = 20)
adaptive = input(title="Adaptive Method", options=["Off", "Cos IFM", "I-Q IFM", "Average"], defval="Cos IFM")
GainLimit = input(title="Gain Limit", defval = 8)
Threshold = input(title="Threshold", defval=0.05, step=0.01)
fixedSL = input(title="SL Points", defval=70)
fixedTP = input(title="TP Points", defval=10)
risk = input(title='Risk', defval=0.01, step=0.01)
// === INPUT BACKTEST RANGE ===
FromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12)
FromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31)
FromYear = input(defval = 2019, title = "From Year", minval = 2015)
ToMonth = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
ToDay = input(defval = 1, title = "To Day", minval = 1, maxval = 31)
ToYear = input(defval = 9999, title = "To Year", minval = 2015)
// === FUNCTION EXAMPLE ===
start = timestamp(FromYear, FromMonth, FromDay, 00, 00) // backtest start window
finish = timestamp(ToYear, ToMonth, ToDay, 23, 59) // backtest finish window
window() => true
range = 50 //input(title="Max Period", defval=60, minval=8, maxval=100)
PI = 3.14159265359
lenIQ = 0.0
lenC = 0.0
//##############################################################################
//I-Q IFM
//##############################################################################
if(adaptive=="I-Q IFM" or adaptive=="Average")
imult = 0.635
qmult = 0.338
inphase = 0.0
quadrature = 0.0
re = 0.0
im = 0.0
deltaIQ = 0.0
instIQ = 0.0
V = 0.0
P = src - src[7]
inphase := 1.25*(P[4] - imult*P[2]) + imult*nz(inphase[3])
quadrature := P[2] - qmult*P + qmult*nz(quadrature[2])
re := 0.2*(inphase*inphase[1] + quadrature*quadrature[1]) + 0.8*nz(re[1])
im := 0.2*(inphase*quadrature[1] - inphase[1]*quadrature) + 0.8*nz(im[1])
if (re!= 0.0)
deltaIQ := atan(im/re)
for i=0 to range
V := V + deltaIQ[i]
if (V > 2*PI and instIQ == 0.0)
instIQ := i
if (instIQ == 0.0)
instIQ := nz(instIQ[1])
lenIQ := 0.25*instIQ + 0.75*nz(lenIQ[1])
//##############################################################################
//COSINE IFM
//##############################################################################
if(adaptive == "Cos IFM" or adaptive == "Average")
s2 = 0.0
s3 = 0.0
deltaC = 0.0
instC = 0.0
v1 = 0.0
v2 = 0.0
v4 = 0.0
v1 := src - src[7]
s2 := 0.2*(v1[1] + v1)*(v1[1] + v1) + 0.8*nz(s2[1])
s3 := 0.2*(v1[1] - v1)*(v1[1] - v1) + 0.8*nz(s3[1])
if (s2 != 0)
v2 := sqrt(s3/s2)
if (s3 != 0)
deltaC := 2*atan(v2)
for i = 0 to range
v4 := v4 + deltaC[i]
if (v4 > 2*PI and instC == 0.0)
instC := i - 1
if (instC == 0.0)
instC := instC[1]
lenC := 0.25*instC + 0.75*nz(lenC[1])
if (adaptive == "Cos IFM")
Period := round(lenC)
if (adaptive == "I-Q IFM")
Period := round(lenIQ)
if (adaptive == "Average")
Period := round((lenC + lenIQ)/2)
//##############################################################################
//ZERO LAG EXPONENTIAL MOVING AVERAGE
//##############################################################################
LeastError = 1000000.0
EC = 0.0
Gain = 0.0
EMA = 0.0
Error = 0.0
BestGain = 0.0
alpha =2/(Period + 1)
EMA := alpha*src + (1-alpha)*nz(EMA[1])
for i = -GainLimit to GainLimit
Gain := i/10
EC := alpha*(EMA + Gain*(src - nz(EC[1]))) + (1 - alpha)*nz(EC[1])
Error := src - EC
if(abs(Error)<LeastError)
LeastError := abs(Error)
BestGain := Gain
EC := alpha*(EMA + BestGain*(src - nz(EC[1]))) + (1-alpha)*nz(EC[1])
plot(EC, title="EC", color=orange, linewidth=2)
plot(EMA, title="EMA", color=red, linewidth=2)
//##############################################################################
//Trade Logic & Risk Management
//##############################################################################
buy = crossover(EC,EMA) and 100*LeastError/src > Threshold
sell = crossunder(EC,EMA) and 100*LeastError/src > Threshold
secScaler = secType == "Forex" ? 100000 : secType == "Metal Spot" ? 100 : secType == "Cryptocurrency" ? 10000 : secType == "Custom" ? contracts : 0
strategy.initial_capital = 50000
balance = strategy.initial_capital + strategy.netprofit
if (time>timestamp(2016, 1, 1 , 0, 0) and balance > 0)
//LONG
lots = ((risk * balance)/fixedSL)*secScaler
lots := lots > limit * secScaler ? limit * secScaler : lots
strategy.entry("BUY", strategy.long, oca_name="BUY", when=buy and window())
strategy.exit("B.Exit", "BUY", qty_percent = 100, loss=fixedSL, trail_offset=15, trail_points=fixedTP)
//SHORT
strategy.entry("SELL", strategy.short, oca_name="SELL",when=sell and window())
strategy.exit("S.Exit", "SELL", qty_percent = 100, loss=fixedSL, trail_offset=15, trail_points=fixedTP)
Detail
https://www.fmz.com/strategy/426573
Last Modified
2023-09-13 14:22:55