이 전략은 다양한 차원의 세 가지 기술적 지표를 포함하고 있습니다. 지원/저항 수준, 이동 평균 시스템 및 오시레이터 지표 등이 포함되어 있으며, 더 높은 승률을 위한 단기 트렌드 방향을 결정합니다.
코드는 먼저 표준 피보트 포인트와 피보나치 리트레이싱 레벨을 포함한 가격의 지원/저항 수준을 계산하고 차트에 표시합니다. 이러한 핵심 수준을 깨는 것은 중요한 트렌드 신호를 나타냅니다.
그 다음에는 골든 크로스 및 죽음의 크로스 신호에 대한 볼륨 가중 평균 가격 (VWAP) 과 평균 가격을 계산합니다. 이것은 중장기 트렌드 판단에 속합니다.
마지막으로, 그것은 과잉 구매 및 과잉 판매 신호에 대한 스토카스틱 RSI 오시레이터를 계산합니다. 이것은 과잉 구매 / 과잉 판매 지표에 속합니다.
이 세 차원의 신호를 결합함으로써, 지원/저항, VWAP, 그리고 스토카스틱 RSI가 모두 구매 신호를 내면, 그것은 긴 포지션을 열 것입니다. 모두 판매 신호를 내면, 그것은 짧은 포지션을 열 것입니다.
이 전략의 가장 큰 장점은 다양한 차원의 지표의 조합으로 판단이 더 포괄적이고 정확하며 승률이 높습니다. 먼저 지원/저항 수준이 주요 추세를 정의합니다. 그 다음 VWAP는 중장기 추세를 결정합니다. 마지막으로 스토카스틱 RSI는 과잉 구매/ 과잉 판매 상태를 판단합니다. 세 가지 지표가 동시에 발사되면서 잘못된 신호를 효과적으로 필터링하고 진입 정확도를 향상시킬 수 있습니다.
또한, 이윤을 취하는 기능은 수익의 특정 비율을 차단하는 데 도움이 되고, 위험 관리를 돕습니다.
이 전략의 주요 위험은 의사결정을 위해 모든 지표로부터의 동시에 신호에 의존하는 것입니다. 일부 지표가 잘못된 신호를 내면 잘못된 결정으로 이어질 수 있습니다. 예를 들어, 스토카스틱 RSI가 과잉 구매를 표시하지만 VWAP 및 지원 / 저항이 여전히 상승세를 나타낼 때, 입력하지 않음으로써 구매 기회를 놓칠 수 있습니다.
또한, 지표의 부적절한 매개 변수 조정은 최적화를 위해 반복적인 백테스팅을 필요로하는 잘못된 신호 판단으로 이어질 수 있습니다.
또한, 단기 시장에서 블랙 스완 이벤트는 지표로부터의 신호를 무효화 할 수 있습니다. 이 위험을 보호하기 위해 개별 거래의 하락을 제한하기 위해 스톱 로스 전략을 구현할 수 있습니다.
이 전략은 다음과 같은 측면에서 더 향상될 수 있습니다.
더 정확한 트렌드를 측정하기 위해 볼륨과 같은 더 많은 지표 신호를 포함하십시오.
기계 학습 모델을 추가하여 다차원적 지표에 대해 훈련하고 자동으로 최적의 전략을 발견합니다.
적응 조정을 위한 다른 제품들에 기반한 매개 변수를 최적화합니다.
스톱 로즈와 지점 사이즈를 도입하여 더 나은 리스크 통제를 위해 드라우다운을 기반으로 합니다.
포트폴리오 최적화를 수행하여 다양성을 위한 낮은 상관관계를 가진 제품을 찾습니다.
전체적으로 이 전략은 단기 트렌드 트레이딩에 잘 적합하다. 차원을 넘나들며 신호를 결합함으로써, 더 높은 승률을 위한 상당한 잡음을 필터링할 수 있다. 그러나 더 이상의 향상으로 개선될 수 있는 잘못된 신호의 위험이 남아 있다. 지속적인 최적화로 이 전략은 효율적이고 견고한 단기 시스템으로 발전할 가능성이 있다.
/*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()