동적 매수/매도 볼륨 변동 돌파 전략


생성 날짜: 2023-12-26 11:15:31 마지막으로 수정됨: 2023-12-26 11:15:31
복사: 0 클릭수: 634
avatar of ChaoZhang ChaoZhang
1
집중하다
1623
수행원

동적 매수/매도 볼륨 변동 돌파 전략

개요

이 전략은 사용자 정의 시간 주기 구매 판매량을 통해 다공간 판단, 둘레 VWAP, 브린 띠와 결합하여 필터링, 높은 확률의 트렌드 추적을 구현한다. 동적 스톱 스톱 손실 메커니즘을 도입하는 동시에, 일방적인 위험을 효과적으로 제어 할 수 있다.

전략 원칙

  1. 사용자 정의 시간 주기의 매매량 지수를 계산합니다.
  • BV: 구매량, 저점 구매로 인한 금액
  • SV: 판매량, 최고 판매량으로 인한 판매량
  1. 구매 및 판매량 처리
  • 20주기 EMA를 사용해서 평형화
  • 처리된 매매량에 대한 양과 음의 분리
  1. 지표의 방향을 판단하는 방법
  • 0보다 큰 지표는 상승, 0보다 작은 지표는 하락
  1. VWAP, 브린의 판단과 함께
  • 가격도 VWAP 위에 있고 지표는 더 많은 신호를 보인다고 합니다.
  • 가격 VWAP 아래로 그리고 지표 하향이 상한 신호로
  1. 동적 중지 중지 손실
  • 하루 ATR에 따라 중지 손실 비율을 설정

전략적 이점

  1. 구매와 판매량은 시장의 실제 동력을 반영하고, 트렌드의 잠재적인 에너지를 포착합니다.
  2. 둘레 VWAP는 대주기 트렌드 방향을 판단하고, 브린은 브레이크 신호를 판단한다
  3. 동적 ATR 설정 스톱 스톱 손실, 최대 수익을 잠금, 과다 조정 방지

전략적 위험

  1. 구매 및 판매량 데이터에 약간의 오류가 있어 판단에 오류가 발생할 수 있습니다.
  2. 단 하나의 지표와 함께 판단하면 잘못된 신호가 발생할 수 있습니다.
  3. 부린벨트 파라미터 설정이 잘못되면, 효과적인 돌파구가 줄어들 수 있습니다.

전략 최적화 방향

  1. 다중 시간 주기 매매량 지표의 최적화
  2. 거래량 증가와 같은 보조 지표를 필터링합니다.
  3. 동적으로 브린 밴드 파라미터를 조정하여 돌파 효율을 높인다.

요약하다

이 전략은 매매량의 예측성을 최대한 활용하고, VWAP와 브린 밴드를 보조하여 높은 확률 신호를 생성하고, 동적 스톱 스톱 로즈를 통해 위험을 효과적으로 제어하는 효율적이고 안정적인 양적 거래 전략이다. 매개 변수 및 규칙의 지속적인 최적화와 함께, 효과는 더 분명해질 것으로 예상된다.

전략 소스 코드
/*backtest
start: 2022-12-19 00:00:00
end: 2023-12-25 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © original author ceyhun
//@ exlux99 update

//@version=5
strategy('Buying Selling Volume Strategy', format=format.volume, precision=0, overlay=false)

weekly_vwap = request.security(syminfo.tickerid, "W", ta.vwap(hlc3))

vi = false
customTimeframe = input.timeframe("60", group="Entry Settings")

allow_long = input.bool(true, group="Entry Settings")
allow_short = input.bool(false, group="Entry Settings")

xVolume = request.security(syminfo.tickerid, customTimeframe, volume)
xHigh = request.security(syminfo.tickerid, customTimeframe, high)
xLow = request.security(syminfo.tickerid, customTimeframe, low)
xClose = request.security(syminfo.tickerid, customTimeframe, close)

BV = xHigh == xLow ? 0 : xVolume * (xClose - xLow) / (xHigh - xLow)
SV = xHigh == xLow ? 0 : xVolume * (xHigh - xClose) / (xHigh - xLow)

vol = xVolume > 0 ? xVolume : 1
TP = BV + SV
BPV = BV / TP * vol
SPV = SV / TP * vol
TPV = BPV + SPV

tavol20 = request.security(syminfo.tickerid, customTimeframe, ta.ema(vol, 20))
tabv20= request.security(syminfo.tickerid, customTimeframe, ta.ema(BV, 20))
tasv20= request.security(syminfo.tickerid, customTimeframe, ta.ema(SV, 20))
VN = vol / tavol20
BPN = BV / tabv20 * VN * 100
SPN = SV / tasv20 * VN * 100
TPN = BPN + SPN

xbvp = request.security(syminfo.tickerid, customTimeframe,-math.abs(BPV))
xbpn = request.security(syminfo.tickerid, customTimeframe,-math.abs(BPN))
xspv = request.security(syminfo.tickerid, customTimeframe,-math.abs(SPV))
xspn = request.security(syminfo.tickerid, customTimeframe,-math.abs(SPN))

BPc1 = BPV > SPV ? BPV : xbvp
BPc2 = BPN > SPN ? BPN : xbpn
SPc1 = SPV > BPV ? SPV : xspv
SPc2 = SPN > BPN ? SPN : xspn
BPcon = vi ? BPc2 : BPc1
SPcon = vi ? SPc2 : SPc1


minus = BPcon + SPcon
plot(minus, color = BPcon > SPcon  ? color.green : color.red , style=plot.style_columns) 

length = input.int(20, minval=1, group="Volatility Settings")
src = minus//input(close, title="Source")
mult = input.float(2.0, minval=0.001, maxval=50, title="StdDev", group="Volatility Settings")
xtasma = request.security(syminfo.tickerid, customTimeframe, ta.sma(src, length))
xstdev = request.security(syminfo.tickerid, customTimeframe, ta.stdev(src, length))
basis = xtasma
dev = mult * xstdev
upper = basis + dev
lower = basis - dev
plot(basis, "Basis", color=#FF6D00, offset = 0)
p1 = plot(upper, "Upper", color=#2962FF, offset = 0)
p2 = plot(lower, "Lower", color=#2962FF, offset = 0)
fill(p1, p2, title = "Background", color=color.rgb(33, 150, 243, 95))

// Original a
longOriginal = minus > upper and BPcon > SPcon and close > weekly_vwap
shortOriginal = minus > upper and BPcon < SPcon and close< weekly_vwap



high_daily = request.security(syminfo.tickerid, "D", high)
low_daily  = request.security(syminfo.tickerid, "D", low)
close_daily = request.security(syminfo.tickerid, "D", close)

true_range = math.max(high_daily - low_daily, math.abs(high_daily - close_daily[1]), math.abs(low_daily - close_daily[1]))
atr_range = ta.sma(true_range*100/request.security(syminfo.tickerid, "D", close), 14)

ProfitTarget_Percent_long = input.float(100.0, title='TP Multiplier for Long entries ', step=0.5, step=0.5, group='Dynamic Risk Management')
Profit_Ticks_long = close + (close * (atr_range * ProfitTarget_Percent_long))/100
LossTarget_Percent_long = input.float(1.0, title='SL Multiplier for Long entries', step=0.5, group='Dynamic Risk Management')
Loss_Ticks_long = close - (close * (atr_range * LossTarget_Percent_long ))/100

ProfitTarget_Percent_short = input.float(100.0, title='TP Multiplier for Short entries ', step=0.5, step=0.5, group='Dynamic Risk Management')
Profit_Ticks_short = close - (close * (atr_range*ProfitTarget_Percent_short))/100
LossTarget_Percent_short = input.float(5.0, title='SL Multiplier for Short entries', step=0.5, group='Dynamic Risk Management')
Loss_Ticks_short = close + (close * (atr_range*LossTarget_Percent_short))/100



var longOpened_original = false
var int timeOfBuyLong = na
var float tpLong_long_original = na
var float slLong_long_original = na
long_entryx = longOriginal

longEntry_original = long_entryx and not longOpened_original 


if longEntry_original
    longOpened_original := true
    tpLong_long_original := Profit_Ticks_long
    slLong_long_original := Loss_Ticks_long
    timeOfBuyLong := time
    //lowest_low_var_sl := lowest_low

     
tpLong_trigger = longOpened_original[1] and ((close > tpLong_long_original) or (high > tpLong_long_original)) //or high > lowest_low_var_tp
slLong_Trigger = longOpened_original[1] and ((close < slLong_long_original) or (low < slLong_long_original)) //or low < lowest_low_var_sl

longExitSignal_original =   shortOriginal or tpLong_trigger or slLong_Trigger 


if(longExitSignal_original)
    longOpened_original := false
    tpLong_long_original := na
    slLong_long_original := na


if(allow_long)
    strategy.entry("long", strategy.long, when=longOriginal) 
    strategy.close("long", when= longExitSignal_original) //or shortNew

if(allow_short)
    strategy.entry("short", strategy.short, when=shortOriginal ) 
    strategy.close("short", when= longOriginal) //or shortNew