3개 이동평균선 교차 + 윌리엄 지표의 양적 거래 전략


생성 날짜: 2023-09-28 10:58:16 마지막으로 수정됨: 2023-09-28 10:58:16
복사: 1 클릭수: 833
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

개요

이 전략은 세 개의 평평한 이동 평균, 상대적으로 강한 지수 ((RSI) 와 윌리엄 지수를 결합하여 주식 가격의 트렌드 방향을 식별하고, 트렌드가 역전될 때 진입 기회를 찾습니다. 세 개의 이동 평균이 상승 (아래) 으로 조화를 이루고, RSI가 높고 (아래) 50보다 낮으며, 하향 (아래) 으로의 윌리엄 지표 신호가 나타나면 더 많은 것을하십시오.

전략 원칙

이 전략은 3개의 다른 주기의 평평한 이동 평균을 사용한다. 이 전략은 빠른 라인, 중간 라인, 그리고 느린 라인을 포함한다. 빠른 라인 상에서 중간 라인을 통과하면 주가가 상승 추세에 들어간다는 것을 나타낸다. 빠른 라인 아래에서 중간 라인을 통과하면 주가가 하향 추세에 들어간다는 것을 나타낸다.

특히, 주가가 상승하는 경향에 들어간 후, 전략은 다음의 다섯 가지 조건이 동시에 충족될 때까지 기다립니다.

  1. 이 모든 것은 빠른 선, 중간 선, 그리고 느린 선이 모두 위로 올라간다는 것을 의미합니다.
  2. RSI가 50보다 높으면
  3. 위르트 지표의 아래로 보이는 형태;
  4. “이런 일이 벌어진다면, 어떻게 해야 할까요?”
  5. 현재 지분 없음.

주가가 하락하는 추세에 들어간 후, 전략은 다음의 다섯 가지 조건이 동시에 충족될 때까지 기다립니다.

  1. 이 모든 것은 아래로 향하고 있습니다.
  2. RSI는 50보다 낮습니다.
  3. 위쪽의 윌리엄스 지표 형태;
  4. 주가 하락,
  5. 현재 지분 없음.

더 많은 상장 후, 전략은 위험을 제어하기 위해 스톱 로즈와 스톱 포인트를 설정합니다. 구체적으로, 스톱 로즈는 입시 가격의 특정 비율이며, 스톱 포인트는 입시 가격이 유리한 방향으로 이동한 이후의 특정 비율입니다.

전략적 이점

  1. 여러 지표와 결합하여 입장을 확인하여 가짜 돌파구를 효과적으로 방지 할 수 있습니다. 세 개의 평행선은 트렌드 방향을 결정하고, 윌리엄 지표는 반전 신호를 캡처하고, RSI 필터는 진동 상황을 필터링하여 입장의 정확도를 향상시킵니다.

  2. 스톱 스톱 손실 지점을 설정하면 각 거래의 리스크 수익률을 잘 제어 할 수 있으며, 이로 인해 수익이있는 거래가 손실이있는 거래보다 크다는 것을 보장 할 수 있습니다.

  3. 전략 논리는 명확하고 이해하기 쉽고, 변수 설정은 합리적이며, 다양한 수준의 거래자가 사용할 수 있습니다.

전략적 위험

  1. 흔들리는 상황에서 지표는 잘못된 신호를 내보낼 수 있으며, 불필요한 입구를 초래할 수 있다. RSI의 매개 변수를 최적화하여 일부 흔들리는 상황을 필터링 할 수 있다.

  2. 빠른선 중선 교차는 가짜 돌파구가 발생할 수 있으며, 다른 지표와 함께 사용해야 한다. 통행량 지표를 추가하는 것을 고려할 수 있다.

  3. 입점 가격과 너무 가까운 곳에 있는 스톱 로즈 포인트는 출구에서 스톱 로즈 될 수 있으며, 스톱 로즈 포인트의 설정은 적절한 위치에 조정할 필요가 있다.

  4. 입점점과 너무 멀리 떨어져 있는 경우 출구를 막을 수 없고, 적절한 위치에 맞춰야 한다.

전략 최적화 방향

  1. 다른 주기의 변수 조합을 테스트할 수 있으며, 삼중평균선과 RSI의 변수를 최적화한다.

  2. 거래량 지표와 같은 다른 지표를 추가하여 거래량이 눈에 띄는지 여부를 판단 할 수 있습니다.

  3. 다양한 품종에 따라 개별적으로 테스트할 수 있는 전략의 매개 변수 설정을 한다.

  4. 재검토 결과에 따라 수익 곡선을 도출할 수 있으며, 스톱로스 스톱 파라미터의 설정을 테스트할 수 있다.

  5. 시작하기 전에 시뮬레이션 거래를 시도할 수 있고, 파라미터를 최적화할 수 있다.

요약하다

이 전략은 전체적으로 논리적으로 명확하며, 지표 조합을 사용하여 입출력을 수행하여 위험을 효과적으로 제어 할 수 있습니다. 전략의 매개 변수를 최적화 할 수있는 공간이 넓고, 다양한 매개 변수 설정을 테스트하여 전략은 안정적으로 수익을 창출하는 정량 거래 전략이 될 수 있습니다. 그러나 어떤 전략도 손실을 완전히 피할 수 없으며, 거래자가 거래 규율을 유지해야하며, 수익이 있으면 중단하고 손실이 있으면 중단됩니다.

전략 소스 코드
/*backtest
start: 2023-08-28 00:00:00
end: 2023-09-27 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//This script is a combination of 3 smoothed moving averages, and RSI. When moving averages are aligned upward (downward) and RSI is above (below) 50 and a down (up) William fractal appears, it enters long (short) position. Exiting from long and short entries are defined by StopLoss and TargetProfit.

//@version=5

strategy(title="3SmmaCrossUp + Fractal + RSI", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, currency=currency.USD, commission_type=strategy.commission.percent, commission_value=0.03)

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// inputs

// Global
src = input(close, title="Source")
stopLoss = input.float(defval = 0.1, title = "Stop Loss %", minval = 0, maxval=100, step = 0.1)
targetProfit = input.float(defval = 0.4, title = "Target Profit %", minval = 0, maxval=100, step = 0.1)

// Smooth Moving Average
fastSmmaLen = input.int(21, minval=1, title="Fast Length", group = "Smooth Moving Average")
midSmmaLen = input.int(50, minval=1, title="Mid Length",group = "Smooth Moving Average")
slowSmmaLen = input.int(200, minval=1, title="Slow Length",group = "Smooth Moving Average")

// RSI
rsiLen = input.int(defval=14, title="length", minval=1, maxval=1000, step=1, group="RSI")

// Fractals
n = input.int(title="Periods", defval=2, minval=2, group = "Fractals")

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// initialization

var waitingFirstTradeInUpwardTrend = false
var waitingFirstTradeInDownwardTrend = false

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// functions

smma(ma, src, len) => 
    smma = 0.0
    smma := na(smma[1]) ? ma : (smma[1] * (len - 1) + src) / len
    smma
    
fractals(n, highs, lows) =>
    // UpFractal
    bool upflagDownFrontier = true
    bool upflagUpFrontier0 = true
    bool upflagUpFrontier1 = true
    bool upflagUpFrontier2 = true
    bool upflagUpFrontier3 = true
    bool upflagUpFrontier4 = true
    for i = 1 to n
        upflagDownFrontier := upflagDownFrontier and (highs[n-i] < highs[n])
        upflagUpFrontier0 := upflagUpFrontier0 and (highs[n+i] < highs[n])
        upflagUpFrontier1 := upflagUpFrontier1 and (highs[n+1] <= highs[n] and highs[n+i + 1] < highs[n])
        upflagUpFrontier2 := upflagUpFrontier2 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+i + 2] < highs[n])
        upflagUpFrontier3 := upflagUpFrontier3 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+3] <= highs[n] and highs[n+i + 3] < highs[n])
        upflagUpFrontier4 := upflagUpFrontier4 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+3] <= highs[n] and highs[n+4] <= highs[n] and highs[n+i + 4] < highs[n])
    flagUpFrontier = upflagUpFrontier0 or upflagUpFrontier1 or upflagUpFrontier2 or upflagUpFrontier3 or upflagUpFrontier4
    
    upFractal = (upflagDownFrontier and flagUpFrontier)
    
    // downFractal
    bool downflagDownFrontier = true
    bool downflagUpFrontier0 = true
    bool downflagUpFrontier1 = true
    bool downflagUpFrontier2 = true
    bool downflagUpFrontier3 = true
    bool downflagUpFrontier4 = true
    
    for i = 1 to n
        downflagDownFrontier := downflagDownFrontier and (lows[n-i] > lows[n])
        downflagUpFrontier0 := downflagUpFrontier0 and (lows[n+i] > lows[n])
        downflagUpFrontier1 := downflagUpFrontier1 and (lows[n+1] >= lows[n] and lows[n+i + 1] > lows[n])
        downflagUpFrontier2 := downflagUpFrontier2 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+i + 2] > lows[n])
        downflagUpFrontier3 := downflagUpFrontier3 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+3] >= lows[n] and lows[n+i + 3] > lows[n])
        downflagUpFrontier4 := downflagUpFrontier4 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+3] >= lows[n] and lows[n+4] >= lows[n] and lows[n+i + 4] > lows[n])
    flagDownFrontier = downflagUpFrontier0 or downflagUpFrontier1 or downflagUpFrontier2 or downflagUpFrontier3 or downflagUpFrontier4
    
    downFractal = (downflagDownFrontier and flagDownFrontier)
    [upFractal, downFractal]

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// calcs

[upFractal, downFractal] = fractals(n, high, low)


rsiIsHigh = ta.rsi(src, rsiLen) >= 50 


slowMa = ta.sma(src, slowSmmaLen)
midMa = ta.sma(src, midSmmaLen)
fastMa = ta.sma(src, fastSmmaLen)

slowSmma = smma(slowMa ,src, slowSmmaLen)
midSmma = smma(midMa, src, midSmmaLen)
fastSmma = smma(fastMa, src, fastSmmaLen)

isFastSmmaUpward = ta.rising(fastSmma, 1)
isMidSmmaUpward = ta.rising(midSmma, 1)
isSlowSmmaUpward = ta.rising(slowSmma, 1)

isFastSmmaDownward = ta.falling(fastSmma, 1)
isMidSmmaDownward = ta.falling(midSmma, 1)
isSlowSmmaDownward = ta.falling(slowSmma, 1)

slowMovingAveragesAreUpward = isMidSmmaUpward and isSlowSmmaUpward
slowMovingAveragesAreDownward = isMidSmmaDownward and isSlowSmmaDownward

justEnteredUpwardTrend = ta.crossover(fastSmma, midSmma) ? true : false
justEnteredDownwardTrend = ta.crossunder(fastSmma, midSmma) ? true : false

waitingFirstTradeInUpwardTrend := justEnteredUpwardTrend == true ? true : (isFastSmmaDownward or isMidSmmaDownward or isSlowSmmaDownward ? false : waitingFirstTradeInUpwardTrend)
waitingFirstTradeInDownwardTrend := justEnteredDownwardTrend == true ? true : (isFastSmmaUpward or isMidSmmaUpward or isSlowSmmaUpward ? false : waitingFirstTradeInDownwardTrend)

priceCrossedOverSlowMa = ta.crossover(close, slowSmma)
priceCrossedUnderSlowMa = ta.crossunder(close, slowSmma)

enterLongCondition = barstate.isconfirmed and low > fastSmma and rsiIsHigh and (downFractal or priceCrossedOverSlowMa) and waitingFirstTradeInUpwardTrend and strategy.position_size == 0

enterShortCondition = barstate.isconfirmed and high < fastSmma and (not rsiIsHigh) and (upFractal or priceCrossedUnderSlowMa) and waitingFirstTradeInDownwardTrend and strategy.position_size == 0

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// strategy

if(enterLongCondition)
    strategy.entry(id="L", direction=strategy.long)
    waitingFirstTradeInUpwardTrend := false

if(enterShortCondition)
    strategy.entry(id="S", direction=strategy.short)
    waitingFirstTradeInDownwardTrend := false
    
if(strategy.position_size > 0)
    strategy.exit(id="EL", stop=strategy.position_avg_price * (1 - stopLoss/100), limit=strategy.position_avg_price * (1+targetProfit/100)) 
if(strategy.position_size < 0)
    strategy.exit(id="ES", stop=strategy.position_avg_price * (1 + stopLoss/100), limit=strategy.position_avg_price * (1-targetProfit/100)) 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// plots

plot(series = slowSmma, title="Slow SMMA", linewidth=3)
plot(series = midSmma, title="Mid SMMA", linewidth=2)
plot(series = fastSmma, title="Fast SMMA", linewidth=1)
plotchar(series=rsiIsHigh, title='rsiIsHigh', char='')
plotchar(series=justEnteredUpwardTrend, title='justEnteredUpwardTrend', char='')
plotchar(series=justEnteredDownwardTrend, title='justEnteredDownwardTrend', char='')
plotchar(series=waitingFirstTradeInUpwardTrend, title='waitingFirstTradeInUpwardTrend', char='')
plotchar(series=waitingFirstTradeInDownwardTrend, title='waitingFirstTradeInDownwardTrend', char='')
plotchar(series=enterLongCondition, title='enterLongCondition' , char='')
plotchar(series=enterShortCondition, title='enterShortCondition' , char='')
plotshape(series=upFractal, title='upFractal', style=shape.triangleup, location=location.abovebar, color=#009688, size = size.tiny)
plotshape(series=downFractal, title='downFractal', style=shape.triangledown, location=location.belowbar, color=color.red, size = size.tiny)