볼링거 밴드 및 RSI 지표 전략

저자:차오장, 날짜: 2023-10-25 14:47:21
태그:

img

전반적인 설명

이 전략은 주로 볼링거 밴드 및 RSI 지표를 결합하여 거래 신호를 판단합니다. 이것은 전형적인 프랭켄슈타인 전략입니다. 볼링거 밴드 (Bollinger Band) 를 통해 트렌드 방향을 판단하고 RSI를 통해 과반 구매 및 과반 판매 상황을 감지하여 입출과 스톱 로스 출출을 통해 다른 지표의 장점을 통합합니다.

전략 원칙

  1. 현재 가격 트렌드를 판단하기 위해 볼링거 밴드의 중간 밴드, 상부 밴드 및 하부 밴드를 사용하십시오. 가격이 상부 밴드를 통과하면 상승 추세로 간주됩니다. 하부 밴드를 통과하면 하향 추세로 간주됩니다.

  2. 볼링거 밴드의 너비 (올래와 하위 밴드 사이의 차이) 는 현재 시장 변동성을 반영 할 수 있습니다. 너비가 증가하면 변동성이 증가한다는 것을 의미하며 RSI는 과잉 구매 및 과잉 판매 상황을 더 잘 감지 할 수 있습니다.

  3. RSI 지표 는 과잉 구매 및 과잉 판매 상황 을 판단 한다. 70 이상 은 과잉 구매 구역 이며 30 이하 는 과잉 판매 구역 이다. 더 나은 위험 보상 비율 을 얻기 위해 과잉 구매 및 과잉 판매 구역 에 들어가는 것 을 피 한다.

  4. 특정 거래 신호: (1) 상승 신호: 가격이 상단 범위를 뚫고 RSI가 과잉 구매되지 않습니다 (RSI 70 이하) (2) 하향 신호: 가격이 하위 범위를 뚫고 RSI가 과잉 판매되지 않습니다 (RSI 30 이상)

  5. 스톱 로스: 긴 트레이드에서는 RSI가 70 이하로 떨어지면 스톱 로스를 합니다. 짧은 트레이드에서는 RSI가 30 이하로 떨어지면 스톱 로스를 합니다.

이점 분석

이 전략의 장점은 다음과 같습니다.

  1. 여러 지표를 통합하면 더 포괄적인 정보와 신뢰할 수 있는 신호가 제공됩니다.

  2. 볼링거 밴드를 사용하여 전체 트렌드를 결정하면 큰 움직임을 잡습니다.

  3. RSI 지표는 또한 지역 과잉 구매 및 과잉 판매 수준을 탐지함으로써 불필요한 위험을 피합니다.

  4. 스톱 로즈 메커니즘은 상당히 엄격해서 손실을 줄이는 데 도움이 됩니다.

위험 분석

이 전략은 또한 다음과 같은 위험을 가지고 있습니다.

  1. 볼링거 밴드와 RSI 모두 실패할 수 있어 잘못된 거래 신호가 나올 수 있습니다.

  2. 스톱 로스가 있긴 하지만, 잘못된 스톱 로스 포인트는 여전히 큰 손실로 이어질 수 있습니다.

  3. 너무 빈번한 거래는 거래 비용과 미끄러짐을 증가시킵니다.

  4. 매개 변수들의 부적절한 최적화는 과도한 부착으로 이어질 수 있습니다.

최적화 방향

이 전략은 다음과 같은 측면에서 최적화 될 수 있습니다.

  1. 최적의 매개 변수를 찾기 위해 다양한 매개 변수 조합을 테스트합니다.

  2. ADDR/ATR 스톱 로스, 트래일링 스톱 로스 등 스톱 로스 방법의 유연성을 높여야 합니다.

  3. 고정 분수, 마틴게일 등 포지션 사이징 전략을 추가합니다.

  4. 부피 등과 같은 신호를 필터하는 더 많은 지표를 포함합니다.

  5. 기계 학습을 이용하여 적응적 매개 변수 최적화를 합니다.

  6. 진입 시기를 최적화하고 진입 전에 확인 신호를 기다립니다.

결론

요약하자면, 이것은 여러 지표를 결합한 전형적인 프랭켄슈타인 전략이다. 이는 과잉 구매 및 과잉 판매 위험을 피하면서 트렌드를 잡기 위해 볼링거 밴드 및 RSI의 장점을 통합합니다. 적절한 매개 변수 최적화 및 스톱 로스 관리로 좋은 결과를 얻을 수 있습니다. 그러나 또한 몇 가지 위험이 있으며 안정성을 향상시키기 위해 추가 최적화가 필요합니다. 전반적으로 전략 아이디어는 합리적이며 개선할 여지가 있습니다.


/*backtest
start: 2023-09-24 00:00:00
end: 2023-10-24 00:00:00
period: 2h
basePeriod: 15m
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/
// © evillalobos1123

//@version=5
strategy("Villa Dinamic Pivot Supertrend Strategy", overlay=true, calc_on_every_tick = true, default_qty_type = strategy.fixed)

//INPUTS

ema_b = input.bool(false, "Use Simple EMA Filter", group = "Strategy Inputs")
ema_b_ang = input.bool(true, "Use DEMA Angle Filter", group = "Strategy Inputs")
dema_b = input.bool(true, "Use DEMA Filter", group = "Strategy Inputs")
st_sig = input.bool(false, "Take Every Supertrend Signal" , group = "Strategy Inputs")
take_p = input.bool(true, "Stop Loss at Supertrend", group = "Strategy Inputs")
din_tp = input.bool(false, "2 Steps Take Profit", group = "Strategy Inputs")
move_sl = input.bool(true, "Move SL", group = "Strategy Inputs")
sl_atr = input.float(2.5, "Stop Loss ATR Multiplier", group = "Strategy Inputs")
tp_atr = input.float(4, "Take Profit ATR Multiplier", group = "Strategy Inputs")
din_tp_qty = input.int(50, "2 Steps TP qty%", group = "Strategy Inputs")
dema_a_filter = input.float(0, "DEMA Angle Threshold (+ & -)", group = "Strategy Inputs")
dema_a_look = input.int(1, "DEMA Angle Lookback", group = "Strategy Inputs")
dr_test = input.string("Backtest", "Testing", options = ["Backtest", "Forwardtest", "All"], group = "Strategy Inputs")

not_in_trade = strategy.position_size == 0

//Backtesting date range

start_year = input.int(2021, "Backtesting start year", group = "BT Date Range")
start_month = input.int(1, "Backtesting start month", group = "BT Date Range")
start_date = input.int(1, "Backtesting start day", group = "BT Date Range")
end_year = input.int(2021, "Backtesting end year", group = "BT Date Range")
end_month = input.int(12, "Backtesting end month", group = "BT Date Range")
end_date = input.int(31, "Backtesting end day", group = "BT Date Range")

bt_date_range = (time >= timestamp(syminfo.timezone, start_year,
         start_month, start_date, 0, 0)) and
     (time < timestamp(syminfo.timezone, end_year, end_month, end_date, 0, 0))
     

//Forward testing date range

start_year_f = input.int(2022, "Forwardtesting start year", group = "FT Date Range")
start_month_f = input.int(1, "Forwardtesting start month", group = "FT Date Range")
start_date_f = input.int(1, "Forwardtesting start day", group = "FT Date Range")
end_year_f = input.int(2022, "Forwardtesting end year", group = "FT Date Range")
end_month_f = input.int(03, "Forwardtesting end month", group = "FT Date Range")
end_date_f = input.int(26, "Forwardtesting end day", group = "FT Date Range")

ft_date_range = (time >= timestamp(syminfo.timezone, start_year_f,
         start_month_f, start_date_f, 0, 0)) and
     (time < timestamp(syminfo.timezone, end_year_f, end_month_f, end_date_f, 0, 0))


//date condition
date_range_cond = if dr_test == "Backtest"
    bt_date_range
else if dr_test == "Forwardtest"
    ft_date_range
else
    true
    

//INDICATORS

//PIVOT SUPERTREND
prd = input.int(2, "PVT ST Pivot Point Period", group = "Pivot Supertrend")
Factor=input.float(3, "PVT ST ATR Factor", group = "Pivot Supertrend")
Pd=input.int(9 ,  "PVT ST ATR Period", group = "Pivot Supertrend")

// get Pivot High/Low
float ph = ta.pivothigh(prd, prd)
float pl = ta.pivotlow(prd, prd)

// calculate the Center line using pivot points
var float center = na
float lastpp = ph ? ph : pl ? pl : na
if lastpp
    if na(center)
        center := lastpp
    else
        //weighted calculation
        center := (center * 2 + lastpp) / 3

// upper/lower bands calculation
Up = center - (Factor * ta.atr(Pd))
Dn = center + (Factor * ta.atr(Pd))

// get the trend
float TUp = na
float TDown = na
Trend = 0
TUp := close[1] > TUp[1] ? math.max(Up, TUp[1]) : Up
TDown := close[1] < TDown[1] ? math.min(Dn, TDown[1]) : Dn
Trend := close > TDown[1] ? 1: close < TUp[1]? -1: nz(Trend[1], 1)
Trailingsl = Trend == 1 ? TUp : TDown

// check and plot the signals
bsignal = Trend == 1 and Trend[1] == -1
ssignal = Trend == -1 and Trend[1] == 1

//get S/R levels using Pivot Points
float resistance = na
float support = na
support := pl ? pl : support[1]
resistance := ph ? ph : resistance[1]

//DEMA

dema_ln = input.int(200, "DEMA Len", group = 'D-EMAs')
dema_src = input.source(close, "D-EMAs Source", group = 'D-EMAs')
ema_fd = ta.ema(dema_src, dema_ln)
dema = (2*ema_fd)-(ta.ema(ema_fd,dema_ln))

//EMA

ema1_l = input.int(21, "EMA 1 Len", group = 'D-EMAs')
ema2_l = input.int(50, "EMA 2 Len", group = 'D-EMAs')
ema3_l = input.int(200, "EMA 3 Len", group = 'D-EMAs')

ema1 = ta.ema(dema_src, ema1_l)
ema2 = ta.ema(dema_src, ema2_l)
ema3 = ta.ema(dema_src, ema3_l)

//Supertrend
Periods = input.int(21, "ST ATR Period", group = "Normal Supertrend")
src_st = input.source(hl2, "ST Supertrend Source", group = "Normal Supertrend")
Multiplier = input.float(2.0 , "ST ATR Multiplier", group = "Normal Supertrend")
changeATR= true
atr2 = ta.sma(ta.tr, Periods)
atr3= changeATR ? ta.atr(Periods) : atr2
up=src_st-(Multiplier*atr3)
up1 = nz(up[1],up)
up := close[1] > up1 ? math.max(up,up1) : up
dn=src_st+(Multiplier*atr3)
dn1 = nz(dn[1], dn)
dn := close[1] < dn1 ? math.min(dn, dn1) : dn
trend = 1
trend := nz(trend[1], trend)
trend := trend == -1 and close > dn1 ? 1 : trend == 1 and close < up1 ? -1 : trend
buySignal = trend == 1 and trend[1] == -1
sellSignal = trend == -1 and trend[1] == 1

//ATR

atr = ta.atr(14)

///CONDITIONS

//BUY 
/// ema simple
ema_cond_b = if ema_b
    ema1 > ema2 and ema2 > ema3
else
    true

///ema angle

dema_angle_rad = math.atan((dema - dema[dema_a_look])/0.0001)
dema_angle = dema_angle_rad * (180/math.pi)

dema_ang_cond_b = if ema_b_ang
    if dema_angle >= dema_a_filter
        true
    else
        false
else
    true
    


///ema distance

dema_cond_b = if dema_b
    close > dema
else 
    true
    

//supertrends
///if pivot buy sig or (st buy sig and pivot. trend = 1)

pvt_cond_b = bsignal

st_cond_b = if st_sig
    buySignal and Trend == 1
else
    false

st_entry_cond = pvt_cond_b or st_cond_b

///stop loss tp

sl_b = if take_p
    if trend == 1
        up
    else
        close - (atr * sl_atr)
else
    close - (atr * sl_atr)

tp_b = if take_p
    if trend == 1
        close + ((close - up) * (tp_atr / sl_atr))
    else
        close + (atr * tp_atr)
else
    close + (atr * tp_atr)
    
//position size 
init_cap = strategy.equity
pos_size_b = math.round((init_cap * .01) / (close - sl_b))
ent_price = strategy.opentrades.entry_price(strategy.opentrades - 1)
var sl_b_n = 0.0
var tp_b_n = 0.0
longCondition = (ema_cond_b and dema_cond_b and dema_ang_cond_b and st_entry_cond and date_range_cond and not_in_trade)
if (longCondition)
    
    strategy.entry("Long", strategy.long, qty = pos_size_b)
    sl_b_n := sl_b
    tp_b_n := tp_b
    ent_price := strategy.opentrades.entry_price(strategy.opentrades - 1)

if (up[1] < ent_price and up >= ent_price and trend[0] == 1)
    if din_tp
        strategy.close("Long", qty_percent = din_tp_qty)
    if move_sl
        sl_b_n := ent_price

strategy.exit("Exit", "Long", stop =sl_b_n, limit = tp_b_n)   


    

//sell

///ema simple
ema_cond_s = if ema_b
    ema1 < ema2 and ema2 < ema3
else
    true

//ema distance
dema_cond_s = if dema_b
    close < dema
else 
    true

//dema angle
dema_ang_cond_s = if ema_b_ang
    if dema_angle <= (dema_a_filter * -1)
        true
    else
        false
else
    true

//supertrends
///if pivot buy sig or (st buy sig and pivot. trend = 1)

pvt_cond_s = ssignal

st_cond_s = if st_sig
    sellSignal and Trend == -1
else
    false

st_entry_cond_s = pvt_cond_s or st_cond_s

///stop loss tp


sl_s = if take_p
    if trend == -1
        dn
    else
        close + (atr * sl_atr)
else
    close + (atr * sl_atr)

tp_s = if take_p
    if trend == -1
        close - ((dn - close) * (tp_atr / sl_atr))
    else
        close - (atr * tp_atr)
else
    close - (atr * tp_atr)


shortCondition = (ema_cond_s and dema_cond_s and dema_ang_cond_s and st_entry_cond_s and not_in_trade)

pos_size_s = math.round((init_cap * .01) / (sl_s - close))
var sl_s_n = 0.0
var tp_s_n = 0.0
if (shortCondition)
    strategy.entry("Short", strategy.short, qty = pos_size_s)
    sl_s_n := sl_s
    tp_s_n := tp_s
    
if (dn[1] > ent_price and dn <= ent_price and trend[0] == -1)
    if din_tp
        strategy.close("Short", qty_percent = din_tp_qty)
    if move_sl
        sl_s_n := ent_price

strategy.exit("Exit", "Short", stop = sl_s_n, limit = tp_s_n)
    

더 많은