이 문서에서는 거래량 비율을 기반으로 트렌드 방향을 판단하는 양적 전략에 대해 자세히 설명합니다. 이 전략은 다공간 거래량 평균선을 계산하여 구매 판매 신호를 생성합니다.
1 전략
이 전략의 핵심 지표는 공백 거래량이다. 구체적인 계산 단계는 다음과 같다:
[Volume]을 계산합니다.
K선이 다목적이라고 판단할 때, 거래량을 다목적 거래량 (Bull Volume) 으로 기록한다.
K선이 공평하다고 판단할 때, 거래량을 공평방위 거래량으로 기록한다.
각각 다면과 빈면의 트랜잭션의 이동 평균을 계산한다.
다면 이동 평균에서 공백 이동 평균을 통과 할 때, 구매 신호가 발생; 반대로 판매 신호가 발생 .
가격 변화 비율 지표로 필터링하고, 가격이 명확한 추세일 때만 거래한다.
신호에 따라 스톱로스 스톱포인트를 설정하여 수익을 잠금합니다.
이렇게, 거래량의 공백 비율을 통해 트렌드 방향을 판단하고, 가격 변화 비율 지표로 보조적인 필터링을 할 수 있어, 신호 품질을 향상시킬 수 있다. 상쇄장치 설정은 또한 각 거래에 대해 통제 가능한 손실이 있다.
2 전략적 장점
이 전략의 가장 큰 장점은 거래량을 사용하여 트렌드 방향을 판단하는 것입니다. 이것은 가장 기본적인 트렌드 판단 방법 중 하나입니다. 거래량은 시장 참가자의 행동을 반영할 수 있습니다.
또한, 거래량 지표는 앞서 침입 신호를 반영할 수 있으며, 상대적으로 민감하다. 가격 지표만을 이용하는 것과 비교하여, 트렌드 전환을 더 일찍 포착할 수 있다.
마지막으로, 가격 변화율 지표와 결합된 필터링은 신호 품질을 향상시킵니다.
이 전략이 장점이 있기는 하지만, 실전에서는 다음과 같은 위험도 주의해야 합니다.
먼저, 잘못된 신호를 피하기 위해 매출 수량 지표의 매개 변수를 신중하게 설정하십시오.
둘째, 단 하나의 지표에 의존하는 것은 가격의 부진에 취약하다. 여러 가지 지표 조합을 검증해야 한다.
마지막으로, 너무 가까이 스톱를 설정하면 스톱가 깨질 위험이 있습니다.
네 가지 내용
이 글은 거래 비율 판단 트렌드를 활용하는 한 가지 양적 전략에 대해 자세히 소개한다. 이 전략은 다공이 거래량 평균선을 계산하여 거래 신호를 생성할 수 있다. 이 전략은 약간의 선행성이 있지만, 다른 지표와 함께 검증해야 한다. 또한, 적절한 매개 변수 설정과 엄격한 자금 관리도 실행 가능성의 핵심이다.
/*backtest
start: 2023-08-14 00:00:00
end: 2023-09-13 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=4
// Based on Volume Flow v3 indicator by oh92
strategy("Volume Flow BF", overlay=false, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.0)
/////////////// Time Frame ///////////////
testStartYear = input(2017, "Backtest Start Year")
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0)
testStopYear = input(2019, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0)
testPeriod() => true
maType = input(title="Moving Average Type", options=["Simple", "Exponential", "Double Exponential"], defval="Simple")
length = input(6, title="MA Length")
x = input(3.1, title="Factor For Breakout Candle")
// Basic Volume Calcs //
vol = volume
bull = close>open?vol:0
bear = open>close?vol:0
// Double EMA Function //
dema(src, len) => (2 * ema(src, len) - ema(ema(src, len), len))
// BULL Moving Average Calculation
bullma = maType == "Exponential" ? ema(bull, length) :
maType == "Double Exponential" ? dema(bull, length) :
sma(bull, length)
// BEAR Moving Average Calculation //
bearma = maType == "Exponential" ? ema(bear, length) :
maType == "Double Exponential" ? dema(bear, length) :
sma(bear, length)
///////////// Rate Of Change /////////////
source = close
roclength = input(12, minval=1)
pcntChange = input(2, minval=1)
roc = 100 * (source - source[roclength]) / source[roclength]
emaroc = ema(roc, roclength / 2)
isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2))
/////////////// Strategy ///////////////
long = bullma > bearma and isMoving()
short = bullma < bearma and isMoving()
last_long = 0.0
last_short = 0.0
last_long := long ? time : nz(last_long[1])
last_short := short ? time : nz(last_short[1])
long_signal = crossover(last_long, last_short)
short_signal = crossover(last_short, last_long)
last_open_long_signal = 0.0
last_open_short_signal = 0.0
last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1])
last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1])
last_long_signal = 0.0
last_short_signal = 0.0
last_long_signal := long_signal ? time : nz(last_long_signal[1])
last_short_signal := short_signal ? time : nz(last_short_signal[1])
in_long_signal = last_long_signal > last_short_signal
in_short_signal = last_short_signal > last_long_signal
last_high = 0.0
last_low = 0.0
last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])
sl_inp = input(2.0, title='Stop Loss %') / 100
tp_inp = input(900.0, title='Take Profit %') / 100
take_level_l = strategy.position_avg_price * (1 + tp_inp)
take_level_s = strategy.position_avg_price * (1 - tp_inp)
since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1])
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1])
slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na
slShort = strategy.position_avg_price * (1 + sl_inp)
long_sl = in_long_signal ? slLong : na
short_sl = in_short_signal ? slShort : na
/////////////// Execution ///////////////
if testPeriod()
strategy.entry("Long", strategy.long, when=long)
strategy.entry("Short", strategy.short, when=short)
strategy.exit("Long Ex", "Long", stop=long_sl, limit=take_level_l, when=since_longEntry > 0)
strategy.exit("Short Ex", "Short", stop=short_sl, limit=take_level_s, when=since_shortEntry > 0)
///////////// Plotting /////////////
bgcolor(isMoving() ? long ? color.green : short ? color.red : na : color.white, transp=80)
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30)
plot(bullma, color=color.lime, linewidth=1, transp=0, title="Bull MA", transp=10)
plot(bearma, color=color.red, linewidth=1, transp=0, title="Bear MA", transp=10)