다중 지표 결정 기반의 단기 트렌드 전략

저자:차오장, 날짜: 2023-10-25 15:31:30
태그:

img

전반적인 설명

이 전략은 다양한 차원의 세 가지 기술적 지표를 포함하고 있습니다. 지원/저항 수준, 이동 평균 시스템 및 오시레이터 지표 등이 포함되어 있으며, 더 높은 승률을 위한 단기 트렌드 방향을 결정합니다.

전략 논리

코드는 먼저 표준 피보트 포인트와 피보나치 리트레이싱 레벨을 포함한 가격의 지원/저항 수준을 계산하고 차트에 표시합니다. 이러한 핵심 수준을 깨는 것은 중요한 트렌드 신호를 나타냅니다.

그 다음에는 골든 크로스 및 죽음의 크로스 신호에 대한 볼륨 가중 평균 가격 (VWAP) 과 평균 가격을 계산합니다. 이것은 중장기 트렌드 판단에 속합니다.

마지막으로, 그것은 과잉 구매 및 과잉 판매 신호에 대한 스토카스틱 RSI 오시레이터를 계산합니다. 이것은 과잉 구매 / 과잉 판매 지표에 속합니다.

이 세 차원의 신호를 결합함으로써, 지원/저항, VWAP, 그리고 스토카스틱 RSI가 모두 구매 신호를 내면, 그것은 긴 포지션을 열 것입니다. 모두 판매 신호를 내면, 그것은 짧은 포지션을 열 것입니다.

이점 분석

이 전략의 가장 큰 장점은 다양한 차원의 지표의 조합으로 판단이 더 포괄적이고 정확하며 승률이 높습니다. 먼저 지원/저항 수준이 주요 추세를 정의합니다. 그 다음 VWAP는 중장기 추세를 결정합니다. 마지막으로 스토카스틱 RSI는 과잉 구매/ 과잉 판매 상태를 판단합니다. 세 가지 지표가 동시에 발사되면서 잘못된 신호를 효과적으로 필터링하고 진입 정확도를 향상시킬 수 있습니다.

또한, 이윤을 취하는 기능은 수익의 특정 비율을 차단하는 데 도움이 되고, 위험 관리를 돕습니다.

위험 분석

이 전략의 주요 위험은 의사결정을 위해 모든 지표로부터의 동시에 신호에 의존하는 것입니다. 일부 지표가 잘못된 신호를 내면 잘못된 결정으로 이어질 수 있습니다. 예를 들어, 스토카스틱 RSI가 과잉 구매를 표시하지만 VWAP 및 지원 / 저항이 여전히 상승세를 나타낼 때, 입력하지 않음으로써 구매 기회를 놓칠 수 있습니다.

또한, 지표의 부적절한 매개 변수 조정은 최적화를 위해 반복적인 백테스팅을 필요로하는 잘못된 신호 판단으로 이어질 수 있습니다.

또한, 단기 시장에서 블랙 스완 이벤트는 지표로부터의 신호를 무효화 할 수 있습니다. 이 위험을 보호하기 위해 개별 거래의 하락을 제한하기 위해 스톱 로스 전략을 구현할 수 있습니다.

개선 할 기회

이 전략은 다음과 같은 측면에서 더 향상될 수 있습니다.

  1. 더 정확한 트렌드를 측정하기 위해 볼륨과 같은 더 많은 지표 신호를 포함하십시오.

  2. 기계 학습 모델을 추가하여 다차원적 지표에 대해 훈련하고 자동으로 최적의 전략을 발견합니다.

  3. 적응 조정을 위한 다른 제품들에 기반한 매개 변수를 최적화합니다.

  4. 스톱 로즈와 지점 사이즈를 도입하여 더 나은 리스크 통제를 위해 드라우다운을 기반으로 합니다.

  5. 포트폴리오 최적화를 수행하여 다양성을 위한 낮은 상관관계를 가진 제품을 찾습니다.

결론

전체적으로 이 전략은 단기 트렌드 트레이딩에 잘 적합하다. 차원을 넘나들며 신호를 결합함으로써, 더 높은 승률을 위한 상당한 잡음을 필터링할 수 있다. 그러나 더 이상의 향상으로 개선될 수 있는 잘못된 신호의 위험이 남아 있다. 지속적인 최적화로 이 전략은 효율적이고 견고한 단기 시스템으로 발전할 가능성이 있다.


/*backtest
start: 2023-09-24 00:00:00
end: 2023-10-24 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// EmperorBTC's VWAP Indicator & Strategy
//              v2.1
// 
//      coded by Bogdan Vaida

// This indicator was created after EmperorBTC's conditions on Twitter. 
// Good timeframes for it: 30', 15', 5'
// To convert from strategy to study switch the commented lines in the beginning
// and at the end of the script and vice versa.

// What this indicator does is to check if:
// o Pivot Point was crossed
// o Stoch-RSI and VWAP were crossed in current or previous candle
// o Candle (or previous candle) close is in the trend direction
// If all these are true then it will go long or short based on direction.


// FUTURE IDEAS: 
//  - Volume Expansion
//  - Candle Stick patterns

//@version=4

// 🔥Uncomment the line below for the indicator and comment the strategy lines
// study(title="EmperorBTC's VWAP Indicator", shorttitle="EMP-VWAP", overlay=true)

// 🔥 Uncomment the line below for the strategy and comment the above line
strategy(title="EmperorBTC's VWAP Strategy", shorttitle="EMP-VWAP", overlay=true, pyramiding=1)

plotAveragePriceCrossedPivotPoint = input(false, title="Plot Close Price Crossing Pivot Points?", group="Pivot Points")
plotPivotPoints = input(false, title="Plot Pivot Points?", group="Pivot Points")
pivotPointsType = input(title="Pivot Points type", defval="Fibonacci", options=["Fibonacci", "Traditional"], group="Pivot Points")

pivotPointCircleWidth = input(2, title="Width of Pivot Point circles", minval=1, group="Pivot Points")

plotVWAP = input(true, title="Plot VWAP?", group="VWAP")
plotAvgPrice = input(true, title="Plot Average Price?", group="VWAP")
plotVWAPCrossPrice = input(false, title="Plot Price Crossing VWAP?", group="VWAP")
reso = input(title="Period", type=input.resolution, defval="D", group="VWAP")
cumulativePeriod = input(14, "VWAP Cumulative Period", group="VWAP")

plotStochRSICross = input(false, title="Plot StochRSI Cross?", group="StochRSI")
smoothK = input(3, "K", minval=1, group="StochRSI", inline="K&D")
smoothD = input(3, "D", minval=1, group="StochRSI", inline="K&D")
lengthRSI = input(14, "RSI Length", minval=1, group="Stochastic-RSI", inline="length")
lengthStoch = input(14, "Stochastic Length", minval=1, group="Stochastic-RSI", inline="length")
rsiSrc = input(close, title="RSI Source", group="Stochastic-RSI")

plotLong = input(true, title="Plot Long Opportunity?", group="Strategy only")
plotShort = input(true, title="Plot Short Opportunity?", group="Strategy only")
tradingDirection = input(title="Strategy trading Direction: ", defval="L&S", options=["L&S", "L", "S"], group="Strategy only")
takeProfit = input(1.0, title='Take Profit %', group="Strategy only") / 100
plotTP = input(true, title="Plot Take Profit?", group="Strategy only")
startDate = input(title="Start Date", type=input.integer,
     defval=1, minval=1, maxval=31, group="Backtesting range", inline="Start Date")
startMonth = input(title="Start Month", type=input.integer,
     defval=1, minval=1, maxval=12, group="Backtesting range", inline="Start Date")
startYear = input(title="Start Year", type=input.integer,
     defval=2017, minval=1800, maxval=2100, group="Backtesting range", inline="Start Date")
endDate = input(title="End Date", type=input.integer,
     defval=31, minval=1, maxval=31, group="Backtesting range", inline="End Date")
endMonth = input(title="End Month", type=input.integer,
     defval=12, minval=1, maxval=12, group="Backtesting range", inline="End Date")
endYear = input(title="End Year", type=input.integer,
     defval=2050, minval=1800, maxval=2100, group="Backtesting range", inline="End Date")


// PivotPoint code (PVTvX by DGT has some nice code on PP)
candleHigh  = security(syminfo.tickerid,"D", high[1], lookahead=barmerge.lookahead_on)
candleLow   = security(syminfo.tickerid,"D", low[1], lookahead=barmerge.lookahead_on)
candleClose = security(syminfo.tickerid,"D", close[1], lookahead=barmerge.lookahead_on)

pivotPoint = (candleHigh+candleLow+candleClose) / 3

float resistance1 = na
float resistance2 = na
float resistance3 = na
float support1 = na
float support2 = na
float support3 = na

if pivotPointsType == "Fibonacci"
    resistance1 := pivotPoint + 0.382 * (candleHigh - candleLow)
    resistance2 := pivotPoint + 0.618 * (candleHigh - candleLow)
    resistance3 := pivotPoint + (candleHigh - candleLow)
    support1 := pivotPoint - 0.382 * (candleHigh - candleLow)
    support2 := pivotPoint - 0.618 * (candleHigh - candleLow)
    support3 := pivotPoint - (candleHigh - candleLow)
else if pivotPointsType == "Traditional"
    resistance1 := 2 * pivotPoint - candleLow
    resistance2 := pivotPoint + (candleHigh - candleLow)
    resistance3 := candleHigh + 2 * (pivotPoint - candleLow) 
    support1 := 2 * pivotPoint - candleHigh
    support2 := pivotPoint - (candleHigh - candleLow)
    support3 := candleLow - 2 * (candleHigh - pivotPoint)

plot(series = plotPivotPoints ? support1 : na, color=#ff0000, title="S1", style = plot.style_circles, linewidth = pivotPointCircleWidth)
plot(series = plotPivotPoints ? support2 : na, color=#800000, title="S2", style = plot.style_circles, linewidth = pivotPointCircleWidth)
plot(series = plotPivotPoints ? support3 : na, color=#330000, title="S3", style = plot.style_circles, linewidth = pivotPointCircleWidth)
plot(series = plotPivotPoints ? pivotPoint : na, color=#FFA500, title="PP", style = plot.style_circles, linewidth = pivotPointCircleWidth)
plot(series = plotPivotPoints ? resistance1 : na, color=#00FF00, title="R1", style = plot.style_circles, linewidth = pivotPointCircleWidth)
plot(series = plotPivotPoints ? resistance2 : na, color=#008000, title="R2", style = plot.style_circles, linewidth = pivotPointCircleWidth)
plot(series = plotPivotPoints ? resistance3 : na, color=#003300, title="R3", style = plot.style_circles, linewidth = pivotPointCircleWidth)

pivotPointCrossedUp = ((low < support3) and (close > support3)) or ((low < support2) and (close > support2)) or ((low < support1) and (close > support1)) or  ((low < pivotPoint) and (close > pivotPoint))
pivotPointCrossedDown = ((high > support3) and (close < support3)) or ((high > support2) and (close < support2)) or ((high > support1) and (close < support1)) or  ((high > pivotPoint) and (close < pivotPoint))
plotPPColor = pivotPointCrossedUp ? color.green :
     pivotPointCrossedDown ? color.red :
     na

plotshape(series = plotAveragePriceCrossedPivotPoint ? (pivotPointCrossedUp or pivotPointCrossedDown) : na, title="PP Cross", style = shape.triangleup, location=location.belowbar, color=plotPPColor, text="PP", size=size.small)

// VWAP (taken from the TV code)
// There are five steps in calculating VWAP:
//
// 1. Calculate the Typical Price for the period. [(High + Low + Close)/3)]
// 2. Multiply the Typical Price by the period Volume (Typical Price x Volume)
// 3. Create a Cumulative Total of Typical Price. Cumulative(Typical Price x Volume)
// 4. Create a Cumulative Total of Volume. Cumulative(Volume)
// 5. Divide the Cumulative Totals. 
//
// VWAP = Cumulative(Typical Price x Volume) / Cumulative(Volume)

// Emperor's Edition
t = time(reso)
debut = na(t[1]) or t > t[1]

addsource = ohlc4 * volume
addvol = volume
addsource := debut ? addsource : addsource + addsource[1]
addvol := debut ? addvol : addvol + addvol[1]
vwapValue = addsource / addvol

pVWAP = plot(series = plotVWAP ? vwapValue : na, color=color.purple, title="VWAP")
pAvgPrice = plot(series = plotAvgPrice ? ohlc4 : na, color=color.blue, title="PRICE")
fill(pVWAP, pAvgPrice, color = ohlc4 > vwapValue ? color.red : color.green, title="VWAP PRICE FILL")

vwapCrossUp = (low < vwapValue) and (vwapValue < high) and (close > open) // added green candle check
vwapCrossDown = (high > vwapValue) and (vwapValue > low) and (close < open) // added red candle check

plotVWAPColor = vwapCrossUp ? color.green :
     vwapCrossDown ? color.red :
     na
plotshape(series = plotVWAPCrossPrice ? (vwapCrossUp or vwapCrossDown) : na, title="VWAP Cross Price", style=shape.triangleup, location=location.belowbar, color=plotVWAPColor, text="VWAP", size=size.small)


// Stochastic RSI

rsi1 = rsi(rsiSrc, lengthRSI)
k = sma(stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d = sma(k, smoothD)

sRsiCrossUp = k[1] < d[1] and k > d
sRsiCrossDown = k[1] > d[1] and k < d

plotColor = sRsiCrossUp ? color.green :
     sRsiCrossDown ? color.red :
     na
plotshape(series = plotStochRSICross ? (sRsiCrossUp or sRsiCrossDown) : na, title="StochRSI Cross Up", style=shape.triangleup, location=location.belowbar, color=plotColor, text="StochRSI", size=size.small)

// Long Trades
sRsiCrossedUp = sRsiCrossUp or sRsiCrossUp[1]
vwapCrossedUp = vwapCrossUp or vwapCrossUp[1]
// longCond1 = (sRsiCross and vwapCross) or (sRsiCross[1] and vwapCross) or (sRsiCross and vwapCross[1])
longCond1 = (sRsiCrossedUp[1] and vwapCrossedUp[1])
longCond2 = pivotPointCrossedUp[1]
longCond3 = (close[1] > open[1]) and (close > open) // check this
longCond = longCond1 and longCond2 and longCond3
plotshape(series = plotLong ? longCond : na, title="Long", style=shape.triangleup, location=location.belowbar, color=color.green, text="Long", size=size.normal)

// Short Trades
sRsiCrossedDown = sRsiCrossDown or sRsiCrossDown[1]
vwapCrossedDown = vwapCrossDown or vwapCrossDown[1]
shortCond1 = (sRsiCrossedDown[1] and vwapCrossedDown[1])
shortCond2 = pivotPointCrossedDown[1]
shortCond3 = (close[1] < open[1]) and (close < open)
shortCond = shortCond1 and shortCond2 and shortCond3
plotshape(series = plotShort ? shortCond : na, title="Short", style=shape.triangledown, location=location.abovebar, color=color.red, text="Short", size=size.normal)

// alertcondition(condition=longCond, title="Long", message="Going long")
// alertcondition(condition=shortCond, title="Short", message="Going short")

// 🔥 Uncomment the lines below for the strategy and revert for the study
takeProfitLong     = strategy.position_avg_price * (1 + takeProfit)
takeProfitShort     = strategy.position_avg_price * (1 - takeProfit)
exitTp = ((strategy.position_size > 0) and (close > takeProfitLong)) or ((strategy.position_size < 0) and (close < takeProfitShort))
strategy.risk.allow_entry_in(tradingDirection == "L" ? strategy.direction.long : tradingDirection == "S" ? strategy.direction.short : strategy.direction.all)
plot(series = (plotTP and strategy.position_size > 0) ? takeProfitLong : na, title="TP Level",color=color.green, style=plot.style_linebr, linewidth=2)
plot(series = (plotTP and strategy.position_size < 0) ? takeProfitShort : na, title="TP Level",color=color.red, style=plot.style_linebr, linewidth=2)
inDateRange = (time >= timestamp(syminfo.timezone, startYear,
         startMonth, startDate, 0, 0)) and (time < timestamp(syminfo.timezone, endYear, endMonth, endDate, 0, 0))
strategy.entry("VWAP", strategy.long, comment="Long", when=longCond and inDateRange)
strategy.entry("VWAP", strategy.short, comment="Short", when=shortCond and inDateRange)
strategy.close(id="VWAP", when=exitTp)
if (not inDateRange)
    strategy.close_all()

더 많은