리소스 로딩... 로딩...

이동 평균 볼링거 밴드 브레이크업 전략

저자:차오장, 날짜: 2023-12-08 12:11:15
태그:

img

전반적인 설명

이 전략은 간단한 브레이크아웃 거래 전략을 구현하기 위해 이동 평균, 볼링거 밴드 및 UT 봇 알렛 인디케이터를 결합합니다. 가격이 볼링거 상단 범위를 넘어서면 길고 가격이 볼링거 하단 범위를 넘어서면 짧습니다.

전략 논리

  1. 200주기 EMA는 트렌드의 기준으로 작용합니다. EMA 이상의 가격은 상승 추세를 나타내고 EMA 이하의 가격은 하락 추세를 나타냅니다.
  2. UT Bot Alerts 지표는 ATR와 결합하여 구매 및 판매 신호를 생성합니다. 가격과 빠른 EMA가 볼링거 상단역을 넘을 때 긴 신호를 유발합니다. 가격과 빠른 EMA가 볼링거 하단역을 넘을 때 짧은 신호를 유발합니다.
  3. ATR 스톱 손실 표시기는 스톱 손실 포인트를 설정합니다. 스톱 손실 거리는 ATR 값의 1.5 배입니다.
  4. 진입 후, 스톱 로스, 수익 취득 및 손익분기 수준은 위험 보상 비율에 의해 결정됩니다.

이점 분석

  1. 적절한 장기 및 단기 기회를 식별하기 위해 볼링거 대역을 사용하면 수익성이 향상 될 수 있습니다.
  2. UT 봇 알림 표시기는 비교적 정확한 신호를 생성할 수 있습니다.
  3. 스톱 로스 및 취리 수익에 대한 리스크 보상 비율을 채택함으로써 리스크를 효과적으로 제어 할 수 있습니다.

위험 분석

  1. 볼링거 밴드는 범위 기간 동안 잘못된 신호를 생성하는 경향이 있습니다.
  2. ATR는 지연 효과를 가지고 있습니다. 트렌드의 시작에는 스톱 손실 거리가 너무 넓을 수 있습니다.
  3. 부적절한 리스크 보상 비율 설정도 과도한 공격성이나 과도한 보수성으로 이어질 수 있습니다.

최적화 지침

  1. UT Bot Alerts를 다른 지표로 대체해보세요.
  2. ATR의 기간과 곱셈 매개 변수를 최적화하여 더 적합한 스톱 손실 거리를 찾습니다.
  3. 최적의 매개 변수를 찾기 위해 다양한 위험 보상 비율을 테스트합니다.

결론

이 전략은 여러 지표의 강점을 통합하고 상당한 실용성을 가지고 있습니다. 매개 변수 최적화를 통해 안정적이고 신뢰할 수있는 브레이크아웃 시스템이 될 수 있습니다. 그러나 지표 실패와 부적절한 매개 변수에서 발생하는 위험도 주의해야합니다.


/*backtest
start: 2023-11-07 00:00:00
end: 2023-12-07 00:00:00
period: 1h
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/
//@version=5
//Developed by StrategiesForEveryone

strategy("UT Bot alerts strategy", overlay=true, process_orders_on_close = true, initial_capital = 1000000, default_qty_type=strategy.cash, precision = 2, calc_on_every_tick = true, commission_value = 0.03)

// ------ Inputs for calculating position --------

initial_actual_capital = input.float(defval=10000, title = "Enter initial/current capital", group = "Calculate position")
risk_c = input.float(2.5, '% account risk per trade', step=1, group = "Position amount calculator", tooltip = "Percentage of total account to risk per trade. The USD value that should be used to risk the inserted percentage of the account. Appears green in the upper left corner")

// ------ Date filter (obtained from ZenAndTheArtOfTrading) ---------

initial_date = input(title="Initial date", defval=timestamp("10 Feb 2014 13:30 +0000"), group="Time filter", tooltip="Enter the start date and time of the strategy")
final_date   = input(title="Final date", defval=timestamp("01 Jan 2030 19:30 +0000"), group="Time filter", tooltip="Enter the end date and time of the strategy")
dateFilter(int st, int et) => time >= st and time <= et
colorDate = input.bool(defval=false, title="Date background", tooltip = "Add color to the period of time of the strategy tester")
bgcolor(colorDate and dateFilter(initial_date, final_date) ? color.new(color.blue, transp=90) : na)

// ------ Session limits (obtained from ZenAndTheArtOfTrading) -------

timeSession = input(title="Time session", defval="0000-2400", group="Time filter", tooltip="Session time to operate. It may be different depending on your time zone, you have to find the correct hours manually.")
colorBG     = input.bool(title="Session background", defval=false, tooltip = "Add color to session time background")
inSession(sess) => na(time(timeframe.period, sess + ':1234567')) == false
bgcolor(inSession(timeSession) and colorBG ? color.rgb(0, 38, 255, 84) : na)

// ----------- Ema ----------------------

ema = input.int(200, title='Ema length', minval=1, maxval=500, group = "Trend")
ema200 = ta.ema(close, ema)
bullish = close > ema200
bearish = close < ema200
show_ema = input.bool(defval=false, title="Show ema ?", group = "Appearance")
// plot(show_ema ? ema200 : na, title = "Ema", color=color.white, linewidth=2, display = display.all - display.status_line - display.price_scale)

// -------------- UT BOT ALERTS INDICATOR by @QuantNomad -------------------------

// Inputs
a = input(3, title='Key Vaule', group = "UT BOT ALERTS", tooltip = "Higher amount, less trades. Changing this could be useful in some assets or time frames")
c = input(1, title='ATR Period', group = "UT BOT ALERTS", tooltip = "Higher amount, less trades. Changing this could be useful in some assets or time frames")
h = input(false, title='Signals from Heikin Ashi Candles', group = "UT BOT ALERTS")

xATR = ta.atr(c)
nLoss = a * xATR

src = h ? request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, close, lookahead=barmerge.lookahead_off) : close

xATRTrailingStop = 0.0
iff_1 = src > nz(xATRTrailingStop[1], 0) ? src - nLoss : src + nLoss
iff_2 = src < nz(xATRTrailingStop[1], 0) and src[1] < nz(xATRTrailingStop[1], 0) ? math.min(nz(xATRTrailingStop[1]), src + nLoss) : iff_1
xATRTrailingStop := src > nz(xATRTrailingStop[1], 0) and src[1] > nz(xATRTrailingStop[1], 0) ? math.max(nz(xATRTrailingStop[1]), src - nLoss) : iff_2
show_atr_ut = input.bool(defval=false, title="Show atr from ut bot alerts ?", group = "Appearance")
// plot(show_atr_ut ? xATRTrailingStop : na, color = color.orange, linewidth = 2, display = display.all - display.price_scale - display.status_line)

pos = 0
iff_3 = src[1] > nz(xATRTrailingStop[1], 0) and src < nz(xATRTrailingStop[1], 0) ? -1 : nz(pos[1], 0)
pos := src[1] < nz(xATRTrailingStop[1], 0) and src > nz(xATRTrailingStop[1], 0) ? 1 : iff_3

xcolor = pos == -1 ? color.red : pos == 1 ? color.green : color.blue

ema_ut = ta.ema(src, 1)
show_ema_ut = input.bool(defval=false, title="Show ema from ut bot alerts ?", group = "Appearance")
// plot(show_ema_ut ? ema_ut : na, color = color.white, linewidth = 2, display = display.all - display.price_scale - display.status_line)
above = ta.crossover(ema_ut, xATRTrailingStop)
below = ta.crossover(xATRTrailingStop, ema_ut)

buy = src > xATRTrailingStop and above
sell = src < xATRTrailingStop and below
close_buy = src < xATRTrailingStop and below
close_sell = src > xATRTrailingStop and above

barbuy = src > xATRTrailingStop
barsell = src < xATRTrailingStop

show_signals = input.bool(true, title = "Show signals ?", group = "Appearance")
paint_candles = input.bool(false, title = "Paint candles ?", group = "Appearance")

// plotshape(bullish and show_signals ? buy : na, title='Buy', text='Buy', style=shape.labelup, location=location.belowbar, color=color.new(color.green, 0), textcolor=color.new(color.white, 0), size=size.tiny , display = display.all - display.price_scale - display.status_line)
// plotshape(bearish and show_signals ? sell : na, title='Sell', text='Sell', style=shape.labeldown, location=location.abovebar, color=color.new(color.red, 0), textcolor=color.new(color.white, 0), size=size.tiny, display = display.all - display.price_scale - display.status_line)
// plotshape(bullish and show_signals ? close_buy : na, title='Close Buy', text='Cl Buy', style=shape.labelup, location=location.belowbar, color=color.new(color.green, 80), textcolor=color.new(color.white, 0), size=size.tiny, display = display.all - display.price_scale - display.status_line)
// plotshape(bearish and show_signals ? close_sell : na, title='Close Sell', text='Cl Sell', style=shape.labeldown, location=location.abovebar, color=color.new(color.red, 80), textcolor=color.new(color.white, 0), size=size.tiny, display = display.all - display.price_scale - display.status_line)

barcolor(barbuy and paint_candles ? color.green : na)
barcolor(barsell and paint_candles ? color.red : na)

// -------------- Atr stop loss by garethyeo (modified) -----------------

long_condition_atr = src > xATRTrailingStop and above 
short_condition_atr = src < xATRTrailingStop and below 
source_atr = input(close, title='Source', group = "Atr stop loss", inline = "A")
length_atr = input.int(14, minval=1, title='Period', group = "Atr stop loss" , inline = "A")
multiplier = input.float(1.5, minval=0.1, step=0.1, title='Atr multiplier', group = "Atr stop loss", inline = "A", tooltip = "Defines the stop loss distance based on the Atr stop loss indicator") 
show_atr = input.bool(defval = true, title = "Show Atr stop loss ?", group = "Appearance")
var float shortStopLoss = na
var float longStopLoss = na 
var float atr_past_candle_long = na
var float atr_past_candle_short = na
//shortStopLoss = source_atr + ta.atr(length_atr) * multiplier
//longStopLoss = source_atr - ta.atr(length_atr) * multiplier
//atr_past_candle_short = close[1] + ta.atr(length_atr)[1] * multiplier[1]
//atr_past_candle_long = close[1] - ta.atr(length_atr)[1] * multiplier[1]
candle_of_stoploss = input.string(defval = "Current candle", title = "Source of stoploss", group = "Risk management for trades", options = ["Current candle","Past candle"])
if candle_of_stoploss == "Current candle"
    shortStopLoss := source_atr + ta.atr(length_atr) * multiplier
    longStopLoss := source_atr - ta.atr(length_atr) * multiplier
if candle_of_stoploss == "Past candle"
    shortStopLoss := close[1] + ta.atr(length_atr)[1] * multiplier[1]
    longStopLoss := close[1] - ta.atr(length_atr)[1] * multiplier[1]
plot(show_atr and long_condition_atr and bullish ? longStopLoss : na, color = color.white, style = plot.style_circles, linewidth = 2)
plot(show_atr and short_condition_atr and bearish ? shortStopLoss : na, color = color.white, style = plot.style_circles, linewidth = 2)

// ------------- Money management --------------

strategy_contracts = strategy.equity / close
distance_sl_atr_long = -1 * (longStopLoss - close) / close
distance_sl_atr_short = (shortStopLoss - close) / close
risk = input.float(2.5, '% Account risk per trade for backtesting', step=1, group = "Risk management for trades", tooltip = "Percentage of total account to risk per trade")
long_amount = strategy_contracts * (risk / 100) / distance_sl_atr_long
short_amount = strategy_contracts * (risk / 100) / distance_sl_atr_short

// ---- Fixed amounts ----

//fixed_amounts = input.bool(defval = false, title = "Fixed amounts ?", group = "Risk management for trades")
//fixed_amount_input = input.float(defval = 1000, title = "Fixed amount in usd", group = "Risk management for trades")
//if fixed_amounts 
//    long_amount := fixed_amount_input / close
//if fixed_amounts
//    short_amount := fixed_amount_input / close
//
leverage=input.bool(defval=true, title="Use leverage for backtesting ?", group = "Risk management for trades", tooltip = "If it is activated, there will be no monetary units or amount of assets limit for each operation (That is, each operation will not be affected by the initial / current capital since it would be using leverage). If it is deactivated, the monetary units or the amount of assets to use for each operation will be limited by the initial/current capital.")
if not leverage and long_amount>strategy_contracts
    long_amount:=strategy.equity/close

if not leverage and short_amount>strategy_contracts
    short_amount:=strategy.equity/close

// ---------- Risk management ---------------

risk_reward_breakeven_long= input.float(title="Risk/reward for breakeven long", defval=0.75, step=0.1, group = "Risk management for trades")
risk_reward_take_profit_long= input.float(title="Risk/reward for take profit long", defval=3.0, step=0.1, group = "Risk management for trades")
risk_reward_breakeven_short= input.float(title="Risk/reward for break even short", defval=0.75, step=0.1, group = "Risk management for trades")
risk_reward_take_profit_short= input.float(title="Risk/reward for take profit short", defval=3.0, step=0.1, group = "Risk management for trades")
tp_percent=input.float(title="% of trade for first take profit", defval=50, step=5, group = "Risk management for trades", tooltip = "Closing percentage of the current position when the first take profit is reached.")

// ------------ Trade conditions ---------------

bullish := close > ema200
bearish := close < ema200
bought = strategy.position_size > 0
sold = strategy.position_size < 0
buy  := src > xATRTrailingStop and above 
sell := src < xATRTrailingStop and below 
var float sl_long = na
var float sl_short = na 
var float be_long = na
var float be_short = na
var float tp_long = na
var float tp_short = na
if not bought
    be_long:=na
    sl_long:=na
    tp_long:=na
if not sold
    be_short:=na
    sl_short:=na
    tp_short:=na
long_positions = input.bool(defval = true, title = "Long positions ?", group = "Positions management")
short_positions = input.bool(defval = true, title = "Short positions ?", group = "Positions management")

// ---------- Strategy -----------

// Long position 

if not bought and buy  and long_positions and bullish and inSession(timeSession)
    sl_long:=longStopLoss           
    long_stoploss_distance = close - longStopLoss
    be_long := close + long_stoploss_distance * risk_reward_breakeven_long
    tp_long:=close+(long_stoploss_distance*risk_reward_take_profit_long)
    strategy.entry('L', strategy.long, long_amount, alert_message = "Long")
    strategy.exit("Tp", "L", stop=sl_long, limit=tp_long, qty_percent=tp_percent)
    strategy.exit('Exit', 'L', stop=sl_long)
if bought and high > be_long
    sl_long := strategy.position_avg_price
    strategy.exit("Tp", "L", stop=sl_long, limit=tp_long, qty_percent=tp_percent)
    strategy.exit('Exit', 'L', stop=sl_long)
if bought and sell and strategy.openprofit>0
    strategy.close("L", comment="CL")

// Short position

if not sold and sell and short_positions and bearish and inSession(timeSession)
    sl_short:=shortStopLoss
    short_stoploss_distance=shortStopLoss - close  
    be_short:=((short_stoploss_distance*risk_reward_breakeven_short)-close)*-1
    tp_short:=((short_stoploss_distance*risk_reward_take_profit_short)-close)*-1
    strategy.entry("S", strategy.short, short_amount, alert_message = "Short")
    strategy.exit("Tp", "S", stop=sl_short, limit=tp_short, qty_percent=tp_percent)
    strategy.exit("Exit", "S", stop=sl_short)
if sold and low < be_short 
    sl_short:=strategy.position_avg_price
    strategy.exit("Tp", "S", stop=sl_short, limit=tp_short, qty_percent=tp_percent)
    strategy.exit("Exit", "S", stop=sl_short)    
if sold and buy and strategy.openprofit>0
    strategy.close("S", comment="CS") 

// ---------- Draw positions and signals on chart (strategy as an indicator) -------------

if high>tp_long
    tp_long:=na
if low<tp_short
    tp_short:=na
if high>be_long
    be_long:=na
if low<be_short
    be_short:=na

show_position_on_chart = input.bool(defval=true, title="Draw position on chart ?", group = "Appearance", tooltip = "Activate to graphically display profit, stop loss and break even")
// position_price = plot(show_position_on_chart? strategy.position_avg_price : na, style=plot.style_linebr, color = color.new(#ffffff, 10), linewidth = 1, display = display.all - display.status_line - display.price_scale)

// sl_long_price = plot(show_position_on_chart and bought ? sl_long : na, style = plot.style_linebr, color = color.new(color.red, 10), linewidth = 1, display = display.all - display.status_line - display.price_scale)
// sl_short_price = plot(show_position_on_chart and sold ? sl_short : na, style = plot.style_linebr, color = color.new(color.red, 10), linewidth = 1, display = display.all - display.status_line - display.price_scale)

// tp_long_price = plot(strategy.position_size>0 and show_position_on_chart? tp_long : na, style = plot.style_linebr, color = color.new(#4cd350, 10), linewidth = 1, display = display.all - display.status_line - display.price_scale)
// tp_short_price = plot(strategy.position_size<0 and show_position_on_chart? tp_short : na, style = plot.style_linebr, color = color.new(#4cd350, 10), linewidth = 1, display = display.all - display.status_line - display.price_scale)

// breakeven_long = plot(strategy.position_size>0 and high<be_long and show_position_on_chart ? be_long : na , style = plot.style_linebr, color = color.new(#1fc9fd, 60), linewidth = 1, display = display.all - display.status_line - display.price_scale)
// breakeven_short = plot(strategy.position_size<0 and low>be_short and show_position_on_chart ? be_short : na , style = plot.style_linebr, color = color.new(#1fc9fd, 60), linewidth = 1, display = display.all - display.status_line - display.price_scale)

show_break_even_on_chart = input.bool(defval=true, title="Draw first take profit/breakeven price on chart ?", group = "Appearance", tooltip = "Activate to display take profit and breakeven price. It appears as a green point in the chart")
long_stoploss_distance = close - longStopLoss
short_stoploss_distance=shortStopLoss - close
be_long_plot = close + long_stoploss_distance * risk_reward_breakeven_long
be_short_plot =((short_stoploss_distance*risk_reward_breakeven_short)-close)*-1
// plot(show_break_even_on_chart and buy and bullish? be_long_plot : na, color=color.new(#1fc9fd, 10), style = plot.style_circles, linewidth = 2, display = display.all - display.price_scale)
// plot(show_break_even_on_chart and sell and bearish? be_short_plot : na, color=color.new(#1fc9fd, 10), style = plot.style_circles, linewidth = 2, display = display.all - display.price_scale)

// position_profit_long = plot(bought and show_position_on_chart and strategy.openprofit>0 ? close : na, style = plot.style_linebr, color = color.new(#4cd350, 10), linewidth = 1, display = display.all - display.status_line - display.price_scale)
// position_profit_short = plot(sold and show_position_on_chart and strategy.openprofit>0 ? close : na, style = plot.style_linebr, color = color.new(#4cd350, 10), linewidth = 1, display = display.all - display.status_line - display.price_scale)

// fill(plot1 = position_price, plot2 = position_profit_long, color = color.new(#4cd350, 90))
// fill(plot1 = position_price, plot2 = position_profit_short, color = color.new(#4cd350, 90))

// fill(plot1 = position_price, plot2 = sl_long_price, color = color.new(color.red,90))
// fill(plot1 = position_price, plot2 = sl_short_price, color = color.new(color.red,90))

// fill(plot1 = position_price, plot2 = tp_long_price, color = color.new(color.green,90))
// fill(plot1 = position_price, plot2 = tp_short_price, color = color.new(color.green,90))

// --------------- Positions amount calculator  -------------

contracts_amount_c = initial_actual_capital / close
distance_sl_long_c = -1 * (longStopLoss - close) / close 
distance_sl_short_c = (shortStopLoss - close) / close
long_amount_c = close * (contracts_amount_c * (risk_c / 100) / distance_sl_long_c)
short_amount_c = close * (contracts_amount_c * (risk_c / 100) / distance_sl_short_c)
long_amount_lev = close * (contracts_amount_c * (risk_c / 100) / distance_sl_long_c)
short_amount_lev = close * (contracts_amount_c * (risk_c / 100) / distance_sl_short_c)

leverage_for_calculator=input.bool(defval=true, title="Use leverage ?", group = "Calculate position", tooltip = "If it is activated, there will be no monetary units or amount of assets limit for each operation (That is, each operation will not be affected by the initial / current capital since it would be using leverage). If it is deactivated, the monetary units or the amount of assets to use for each operation will be limited by the initial/current capital.")

if not leverage_for_calculator and long_amount_lev>initial_actual_capital
    long_amount_lev:=initial_actual_capital

if not leverage_for_calculator and short_amount_lev>initial_actual_capital
    short_amount_lev:=initial_actual_capital

// plot(buy and leverage_for_calculator ? long_amount_c : na, color = color.rgb(136, 255, 0), display = display.all - display.pane - display.price_scale)
// plot(sell and leverage_for_calculator ? short_amount_c : na, color = color.rgb(136, 255, 0), display = display.all - display.pane - display.price_scale)
// plot(buy and not leverage_for_calculator ? long_amount_lev : na, color = color.rgb(136, 255, 0), display = display.all - display.pane - display.price_scale)
// plot(sell and not leverage_for_calculator ? short_amount_lev : na, color = color.rgb(136, 255, 0), display = display.all - display.pane - display.price_scale)



더 많은