DCA 전략과 결합한 볼링거 대역 및 RSI

저자:차오장, 날짜: 2024-01-18 11:23:15
태그:

img

전반적인 설명

이 전략은 DCA와 볼링거 밴드 및 RSI 혼합 (Bollinger Band and RSI Mixing with DCA) 이라고 불린다. 볼링거 밴드 및 상대적 강도 지표 (RSI) 인디케이터를 기반으로 거래 신호를 구축하고 프로그레시브 달러 비용 평균 (DCA) 을 사용하여 위험을 관리한다. 주요 아이디어는 인디케이터를 사용하여 황소 시장의 추세를 파악하고 프로그레시브 DCA를 통해 하락 시장에서 비용을 줄이는 것이다.

전략 원칙

이 전략은 볼링거 밴드 및 RSI 지표를 통합합니다. 볼링거 밴드는 중간 밴드 위에 황소 시장을 의미하고 아래에 곰 시장을 의미하는 경향을 명확히 판단합니다. RSI는 과잉 구매 및 과잉 판매 상황을 나타냅니다. 전략은 볼링거 밴드 오차와 RSI의 K 값을 가중화하여 MIX 지표를 만듭니다. MIX 지표가 아래에서 20을 넘을 때 긴 신호가 생성됩니다.

프로그레시브 DCA 부분에서는 MIX가 20을 넘을 때 초기 포지션이 열립니다. 가격은 일정한 비율로 떨어질 때마다 추가 포지션이 일정한 금액으로 추가됩니다. 최대 포지션이 도달하거나 스톱 로스 / 테이크 이윤이 유발 될 때까지 계속됩니다. 시장 최저 수준의 포지션을 여러 번 추가하면 평균 비용이 점차 낮아질 수 있습니다.

전략 의 장점

  1. 두 개의 지표를 결합하면 더 명확한 트렌드 판단으로 신호 정확도가 향상됩니다.

  2. 점진적인 DCA는 하락 기간 동안 비용 기반을 낮추고 손실 위험을 줄이고 수익 범위를 증가시킵니다.

  3. 이윤을 취하고 손실을 멈추는 조건은 즉시 위험을 제어하고 부분적인 이익을 잠금합니다.

  4. 추가된 날짜 범위 필터는 특정 기간의 집중된 백테스트와 최적화를 허용합니다.

위험 과 해결책

  1. 볼링거 대역과 RSI 모두 실패를 겪을 수 있습니다. 최고의 신호 정확성을 위해 다른 매개 변수 조합을 테스트 할 수 있습니다.

  2. 프로그레시브 DCA는 지속적으로 포지션을 추가함으로써 큰 충돌 중 손실을 증가시킬 수 있습니다. 더 나은 위험 통제를 위해 적절한 스톱 로스 수준과 함께 최대 엔트리를 설정할 수 있습니다.

  3. 블랙 스완 이벤트 및 비정상적인 가격 움직임은 예측할 수 없습니다. 주요 인덱스를 사용하는 시스템 리스크 필터는 비정상적인 시기를 피하는 데 도움이 될 수 있습니다.

최적화 방향

  1. 더 정확한 거래 신호를 얻기 위해 MIX 지표의 매개 변수를 테스트하고 최적화하십시오.

  2. 최대의 수익/손실 비율을 위해 스톱 로스를 최적화하고, 이윤 매개 변수를 취합니다.

  3. 최적의 조합을 찾기 위해 다른 덧셈 위치 크기와 주파수를 테스트합니다.

  4. 거래량 조절 모듈을 거래량 조건에 기반한 오픈/클로즈 전략에 추가하는 것을 고려하십시오.

요약

DCA 전략과 함께 볼링거 밴드 및 RSI 혼합 은 여러 양의 기술과 방법을 결합합니다. 그것은 명확한 트렌드 판단 지표를 구축하고 점진적 인 추가로 비용 기반을 낮추고 있습니다. 스톱 로스 및 수익을 취하는 것을 포함한 엄격한 리스크 제어 방법이 실용적입니다. 추가 테스트와 최적화는 수익성있는 거래 시스템으로 고유 한 장점을 해제 할 수 있습니다. 이윤 추구와 위험 통제를 염두에두고 실시간 거래 및 응용 프로그램으로 검증 할 가치가 있습니다.


/*backtest
start: 2023-01-11 00:00:00
end: 2024-01-17 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// © lagobrian23
//@version=4
strategy(title = 'Bollinger Bands and RSI mix with DCA', shorttitle = 'BB/RSI with DCA',pyramiding = 20, calc_on_every_tick = true, overlay = false )
source=close
smoothK = input(3, "K", minval=1)
smoothD = input(3, "D", minval=1)
lengthRSI = input(14, "RSI Length", minval=1)
lengthStoch = input(14, "Stochastic Length", minval=1)
src = input(close, title="RSI Source")
rsi1 = rsi(src, lengthRSI)
k = sma(stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d = sma(k, smoothD)

// Bollinger Band

length = input(20,title = 'BB lookback length', minval=1)
mult = input(2.0, minval=0.001, maxval=50, title="StdDev")
basis = sma(src, length)
dev = mult * stdev(src, length)
upper = basis + dev
lower = basis - dev
BBval = (src - basis)/dev*30+50
offset = input(0, title = "Offset", type = input.integer, minval = -500, maxval = 500)
mix=(d + BBval)/2

//plot
//plot(k, "K", color=#606060)
plot(BBval, "BBval", color=#872323, offset = offset)
plot(d, "D", color=#FF6A00)
h0 = hline(80, "Upper Band", color=#606060)
h1 = hline(20, "Lower Band", color=#606060)
plot(mix, "MIX", color=#888888, linewidth=3)

//background MIX
bgcolor(mix < 20 ? color.green : color.white, transp=50)
bgcolor(mix > 80 ? color.red : color.white, transp=50)

// Choosing the date range
fromMonth = input(defval = 1,    title = "From Month",      type = input.integer, minval = 1, maxval = 12)
fromDay   = input(defval = 1,    title = "From Day",        type = input.integer, minval = 1, maxval = 31)
fromYear  = input(defval = 2020, title = "From Year",       type = input.integer, minval = 1970)
toMonth = input(defval = 1,    title = "To Month",      type = input.integer, minval = 1, maxval = 12)
toDay   = input(defval = 1,    title = "To Day",        type = input.integer, minval = 1, maxval = 31)
toYear  = input(defval = 2112, title = "To Year",       type = input.integer, minval = 1970)

start     = timestamp(fromYear, fromMonth, fromDay, 00, 00)        // backtest start window
finish    = timestamp(toYear, toMonth, toDay, 23, 59)        // backtest finish window
window()  => true

// Initializing the strategy paraeters

P = input(defval = 1, title = 'Amount (P)' , type = input.integer, minval = 1, maxval = 100)
X = input(defval = 2, title = '% Price drop for consecutive entries(X)', type = input.float, minval = 1, maxval = 100)
B_tp = input(defval = 10, title = '% Level for Take Profit (B)', type = input.float , minval = 1, maxval = 100)
D_sl = input(defval = 10, title = '% Level for Stop Loss (D)', type = input.float, minval = 1, maxval = 100)
A = input(defval = 5, title = 'Max consecutive entries (A)', type = input.integer, minval = 2, maxval = 20)
Z = input(defval = 0.5, title = 'Z', type = input.float , minval = 0, maxval = 10)

// Declaring key DCA variables
entry_price = 0.0
entry_price := na(entry_price[1]) ? na : entry_price[1]
new_entry = 0.0
consec_entryCondition = false
// Implementing the strategy
longEntry = crossover(mix,20)
exitLongs = crossunder(mix, 80)

if(longEntry)
    entry_price := close
    strategy.entry('main_LE', strategy.long , P, when = window() and longEntry)

// Exiting conditions
stoploss = strategy.position_avg_price*(1-(D_sl/100))
takeprofit = strategy.position_avg_price*(1+(B_tp/100))
slCondition = crossunder(close, stoploss)
tpCondition = crossover(close, takeprofit)

// We want to exit if the 'mix' indicator crosses 80, take profit is attained or stop loss is tagged.
exitConditions = exitLongs or slCondition or tpCondition

// Consecutive entries upto A times
// strategy.risk.max_intraday_filled_orders(A)

//Dollar-Cost-Averaging
// Enter long whenever price goes down X%: amount set to (P+Y)*Z
newAmount = (P+X)*Z
// If we haven't reached max open trades, buy newAmount immediately price crosses under X% lower the previous entry price
new_entry := entry_price - ((X/100)*entry_price)
consec_entryCondition := crossunder(close, new_entry)
if(consec_entryCondition and strategy.opentrades != A)
    strategy.entry('consec_LE', strategy.long, newAmount, oca_name = 'consecLongs', when = window() and consec_entryCondition)
    entry_price := close
    
// Exiting
// The main trade is closed only when the  main exit conditions are satisfied
strategy.close('main_LE', comment = 'Main Long Closed', when = window() and exitConditions)

// A consective long is closed only when tp or sl is tagged
strategy.exit('ext a consec', 'consec_LE', loss = D_sl*strategy.position_avg_price , profit = B_tp*strategy.position_avg_price, oca_name =  'consecLongs')


더 많은