적응성 제로 레이그 EMA 거래 전략

저자:차오장, 날짜: 2023-09-13 14:22:55
태그:

이 전략은 트렌드 결정 및 거래 신호를 위해 적응적 제로 레이그 EMA 지표를 사용합니다. 적응적 EMA는 레이그를 제거하기 위해 매개 변수를 동적으로 조정합니다. 트렌드를 따르는 것을 목표로합니다.

전략 논리:

  1. 코시노스 및 I-Q 적응 알고리즘으로 적응적 제로 Lag EMA를 계산합니다.

  2. EMA는 정상 EMA, EC는 적응적 제로 레이그 EMA입니다.

  3. EC가 EMA를 넘을 때 길고, EMA를 넘을 때 짧습니다.

  4. 오류 곡선을 계산하고 잘못된 신호를 필터링하기 위해 임계치를 설정합니다.

  5. 스톱 로스를 위해 고정된 지점을 사용하고 리스크 통제를 위해 수익을 취하십시오.

장점:

  1. 적응성 EMA는 지표 지연을 크게 줄입니다.

  2. 임계 필터링은 신호 품질을 향상시키고 잘못된 파장을 방지합니다.

  3. 간단한 정지 및 목표가 쉽게 실행됩니다.

위험성:

  1. 적응적인 EMA 매개 변수는 불안정해질 수 있습니다.

  2. 고정된 정지/목표는 변화하는 시장 조건에 적응하지 못합니다.

  3. 손실 규모에 제한이 없습니다. 큰 손실 거래의 위험이 있습니다.

요약하자면, 이 전략은 트렌드를 따르는 데 적응 EMA를 사용하며, 어느 정도 지연을 줄입니다. 그러나 위험 통제를 위해 매개 변수 안정성과 최적화된 중지가 필요합니다.


/*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)


더 많은