유동평균 파업에 기초한 트렌드 추종 전략

저자:차오장, 날짜: 2023-10-30 12:22:28
태그:

img

전반적인 설명

이 전략의 핵심 아이디어는 더 높은 시간 프레임에 걸쳐 이동 평균의 브레이크를 탐지함으로써 트렌드를 추적하는 것입니다. 가격이 더 높은 시간 프레임에서 이동 평균보다 높거나 낮을 때 새로운 트렌드의 잠재적 시작을 신호하여 거래자가 이에 따라 포지션을 취하도록합니다.

전략 논리

이 전략은 파인 스크립트로 개발되었으며 다음과 같은 주요 구성 요소로 구성됩니다.

  1. 입력물

    입력 매개 변수 기간을 이동 평균 기간으로 정의합니다. 기본값은 200입니다. 시간 프레임은 바 시간 프레임으로 정의합니다. 기본값은 D (일간 바) 입니다.

  2. 이동 평균

    ta.ema 함수를 사용하여 지수적인 이동 평균 (EMA) 을 계산합니다.

  3. 침투 탐지

    ta.crossover 및 ta.crossunder 함수를 사용하여 파업 및 파업을 식별합니다.

  4. 신호 도표

    피난이 발생했을 때 막대기에 올라가고 내려가는 화살표입니다.

  5. 무역 진입 및 출입

    브레이크오웃 신호에 따라 거래에 들어가고 가격이 2배의 스톱 로스 거리에 도달했을 때 종료합니다.

이 전략은 주로 더 높은 시간 프레임에 걸쳐 이동 평균의 트렌드를 따르는 능력을 활용합니다. 트렌드 거래를 위해 간단한 브레이크아웃 논리를 구현하여 전통적인 브레이크아웃 전략입니다.

이점 분석

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

  1. 간단한 논리, 이해하기 쉽고 마스터하기 쉽습니다.

  2. 단 하나의 지표에 의존하고 최소한의 매개 변수를 조정합니다

  3. 브레이크오웃 신호는 트렌드에 맞춰서 과도한 거래를 피하는 경향이 있습니다.

  4. 더 높은 시간 프레임은 큰 트렌드를 노이즈없이 명확하게 나타냅니다.

  5. 유연한 기간 조합은 다양한 제품을 충족시킵니다.

  6. 제품마다 쉽게 확장할 수 있어 동시에 사용량을 줄일 수 있습니다.

위험 분석

잠재적인 위험은 다음과 같습니다.

  1. 브레이크오웃 신호는 잘못된 신호로 판명될 수 있고 시장 소음을 효과적으로 필터링할 수 없습니다.

  2. 단기적인 기회를 활용할 수 없습니다.

  3. 주요 트렌드 방향이 잘못되면 엄청난 손실이 발생합니다.

  4. 이동평균과 거래 시간 프레임 사이의 시간 프레임 불일치는 과도한 거래 또는 손실 수익으로 이어질 수 있습니다.

  5. 실시간 스톱 손실이 없으면 손실이 커질 수 있습니다.

가능한 해결책은 트렌드를 따르는 지표와 결합하고 필터를 추가하고, 보유 기간을 단축하고, 동적 스톱 로스를 구현하는 등입니다.

더 나은 기회

이 전략은 다음과 같은 측면에서 개선될 수 있습니다.

  1. 트렌드를 따르는 MACD, KD와 같은 지표를 추가하여 브레이크오웃 신뢰성을 높입니다.

  2. 부피나 볼링거 밴드를 기준으로 필터를 추가하여 잘못된 브레이크를 피합니다.

  3. 매개 변수 조절을 최적화하여 유지 기간과 트렌드 사이클을 일치시킵니다.

  4. 단일 트레이드 손실을 제어하기 위해 실시간 스톱 손실을 포함합니다.

  5. 동적 매개 변수 최적화를 위한 기계 학습 기술을 탐구합니다.

  6. 전체적인 안정성을 높이기 위해 다양한 자산 할당 조합을 테스트합니다.

결론

요약하자면, 이것은 이동 평균 브레이크오웃을 통해 트렌드를 따르는 간단하고 실용적인 전략입니다. 이해하고 구현하기 쉽고, 알고 트레이딩에 좋은 도입 전략으로 작용합니다. 그러나 지표 조합, 매개 변수 조정, 동적 스톱 로스 등을 통해 해결해야 할 몇 가지 결함이 있습니다. 개선 및 확장을위한 많은 공간이 남아 있습니다.


/*backtest
start: 2023-09-29 00:00:00
end: 2023-10-29 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// @version=5
// Open-Range-Breakout strategy
// No license. Free and Open Source.    

strategy('Strategy: ORB', shorttitle="ORB", overlay=true , currency=currency.NONE, initial_capital=100000)

// Inputs
period = input.int(defval=15, title="TimeRange", tooltip="The range in minutes (default: 15m)")
sessionInput = input(defval="0915-0930", title="Time Range", group="ORB settings", tooltip='What is the timeperiod (default 9:15AM to 9:30AM, exchange timezone')
hide = input.bool(defval = false, title="Hide ORB Range", group="ORB setting", tooltip = 'Hide the ORB range drawing')

// SL Related
slAtrLen = input.int(defval=14, title="ATR Period for placing SL", group="StopLoss settings")
showSLLines = input.bool(defval=false, title="Show SL lines in chart", tooltip="Show SL lines also as dotted lines in chart. Note: chart may look untidy.", group="StopLoss settings")

// Further Filtering
ignoreMementumVolume = input.bool(defval=false, title="Ignore Momentum & Volume", tooltip="Ignore Momentum & Volume to find out trades", group="Strengh Settings")
rsiLen = input.int(defval=14, title="Momentum Period", group="Strengh Settings", tooltip = 'To determine the momentum, RSI period is set default to 100')
rsiBullish = input.int(defval=50, step=1, title="Bullish Momentum", group="Strengh Settings", tooltip = 'Bullish Momentum, default set to RSI as 50')
rsiBearish = input.int(defval=50, step=1, title="Bearish Momentum", group="Strengh Settings", tooltip = 'Bearish Momentum, default set to RSI as 50')
volAvg = input.int(defval=20, step=1, title="Volume Average Period", group="Strengh Settings", tooltip = 'To calculate average volume, how many historical bars are considered. Default: 20.')
volThreshold = input.float(defval=1, step=0.1, title="Volume Strengh", group="Strengh Settings", tooltip = 'Multiplier: How big the current bar volume compared to average of last 20')

trendPeriod = input.int(defval=200, step=1, title="Trend Period", group="Trend Settings", tooltip = 'To calculate trend, what period is considered. Default: 200.')
hideTrend = input.bool(defval = false, title="Hide the trend line", group="Trend Settings", tooltip = 'Hide the trend')

hidePDHCL = input.bool(defval = false, title="Hide the PDHCL (prev day High Close Low range)", tooltip = 'Hide the Previous Day High, Close, Low lines')

hideTable = input.bool(defval = false, title="Hide the Summary Table", tooltip = 'Hide the summary table.')

// Trade related
rrRatio = input.float(title='Risk:Reward', step=0.1, defval=2.0, group="Trade settings")
endOfDay = input.int(defval=1500, title="Close all trades, default is 3:00 PM, 1500 hours (integer)", group="Trade settings")
mktAlwaysOn = input.bool(defval=true, title="Markets that never closed (Crypto, Forex, Commodity)", tooltip="Some markers never closes. For those cases, make this checked.", group="Trade settings")
lotSize = input.int(title='Lot Size', step=1, defval=1, group="Trade settings")

// Util method

is_newbar(res) => 
	timeframe.change(time(res)) != 0

// print table
printTable(txt) =>
    var table t = table.new(position.bottom_right, 1, 1)
    table.cell(t, 0, 0, txt, text_halign = text.align_left, bgcolor = color.lime)
	
// globals
t = time(timeframe.period, sessionInput + ":1234567") // everyday
in_session = not na(t)
is_first = in_session and not in_session[1]
is_end_session = in_session[1] and not in_session
green(open, close) => close > open ? true : false
red(open, close) => close < open ? true : false

var float orb_high = na
var float orb_low = na
if is_first
    orb_high := high
    orb_low := low
else
    orb_high := orb_high[1]
    orb_low := orb_low[1]
if high > orb_high and in_session
    orb_high := high
if low < orb_low and in_session
    orb_low := low

plot(hide ? na : orb_high, style=plot.style_line, color=orb_high[1] != orb_high ? na : color.green, title="ORB High", linewidth=2)
plot(hide ? na : orb_low, style=plot.style_line, color=orb_low[1] != orb_low ? na : color.red, title="ORB Low", linewidth=2)



// PDHCL (Previous Day High Close Low)
[dh,dl,dc] = request.security(syminfo.ticker, "D", [high[1],low[1], close[1]], lookahead=barmerge.lookahead_on)
plot(hidePDHCL ? na : dh, title="Prev High",  color=color.red,  linewidth=2, trackprice=true, show_last = 1)
plot(hidePDHCL ? na : dl, title="Prev Low",  color=color.green,  linewidth=2, trackprice=true, show_last = 1)
plot(hidePDHCL ? na : dc, title="Prev Close",  color=color.black,  linewidth=2, trackprice=true, show_last = 1)
plot(hidePDHCL ? na : ta.vwap(close), title="Prev VWAP",  color=color.fuchsia,  linewidth=2, trackprice=true, show_last = 1)

var l1 = label.new(bar_index, hidePDHCL ? na : dh, 'PDH', style=label.style_label_right)

// Previous Day WWAP


// For SL calculation
atr = ta.atr(slAtrLen)	
highestHigh = ta.highest(high, 7)
lowestLow = ta.lowest(low, 7)
longStop = showSLLines ? lowestLow - (atr * 1) : na
shortStop = showSLLines ? highestHigh + (atr * 1) : na
plot(longStop, title="Buy SL", color=color.green, style=plot.style_cross)
plot(shortStop, title="Sell SL", color=color.red, style=plot.style_cross)

// Momentum: rsi
rsi = ta.rsi(close, rsiLen)

// trend: EMA200
ema = ta.ema(close, trendPeriod)
plot(hideTrend ? na : ema, "EMA Trend", color=close > ema ? color.green : color.red, linewidth = 1)

// Volume-Weighed Moving Average calculation
vwmaAvg = ta.vwma(close, volAvg)
vwma_latest = volume
// plotshape((barstate.isconfirmed and (vwma_latest > (vwmaAvg * volThreshold))), title='VolumeData', text='', location=location.abovebar, style=shape.diamond, color=color.gray, textcolor=color.gray, size=size.tiny)

// Trade signals

longCond = barstate.isconfirmed and (ta.crossover(close, orb_high) or ta.crossover(close, dh)) and green(open, close) and (ignoreMementumVolume ? true : rsi > rsiBullish and (vwma_latest > (vwmaAvg * volThreshold)))
shortCond = barstate.isconfirmed and (ta.crossunder(close, orb_low) or ta.crossunder(close, dl)) and red(open, close) and (ignoreMementumVolume ? true : rsi < rsiBearish and (vwma_latest > (vwmaAvg * volThreshold)))

plotshape(longCond, title='Breakout', text='BO', location=location.belowbar, style=shape.triangleup, color=color.green, textcolor=color.green)
plotshape(shortCond, title='Breakout', text='BD', location=location.abovebar, style=shape.triangledown, color=color.red, textcolor=color.red)


// Trade execute
h = hour(time('1'), syminfo.timezone)
m = minute(time('1'), syminfo.timezone)
hourVal = h * 100 + m
totalTrades = strategy.opentrades + strategy.closedtrades
if (mktAlwaysOn or (hourVal < endOfDay))
    // Entry
    var float sl = na
    var float target = na
    if (longCond)
        strategy.entry("enter long", strategy.long, lotSize, limit=na, stop=na, comment="Enter Long")
        sl := longStop
        target := close + ((close - longStop) * rrRatio)
        alert('Buy:' + syminfo.ticker + ' ,SL:' + str.tostring(math.floor(sl)) + ', Target:' + str.tostring(target), alert.freq_once_per_bar)
    if (shortCond)
        strategy.entry("enter short", strategy.short, lotSize, limit=na, stop=na, comment="Enter Short")
        sl := shortStop
        target := close - ((shortStop - close) * rrRatio)
        alert('Sell:' + syminfo.ticker + ' ,SL:' + str.tostring(math.floor(sl)) + ', Target:' + str.tostring(target), alert.freq_once_per_bar)

    // Exit: target or SL
    if ((close >= target) or (close <= sl))
        strategy.close("enter long", comment=close < sl ? "Long SL hit" : "Long target hit")
    if ((close <= target) or (close >= sl))
        strategy.close("enter short", comment=close > sl ? "Short SL hit" : "Short target hit")
else if (not mktAlwaysOn)
    // Close all open position at the end if Day
    strategy.close_all(comment = "Close all entries at end of day.")


// Plotting table
if (not hideTable and is_end_session)
    message =  syminfo.ticker + " :\n\nORB Upper: " + str.tostring(math.round(orb_high)) + "\nORB Lower: " + str.tostring(math.round(orb_low)) + "\nPDH: " + str.tostring(math.round(dh)) + "\nPDC: " + str.tostring(math.round(dc)) + "\nPDL: " + str.tostring(math.round(dl)) + "\nVWAP: " + str.tostring(math.round(ta.vwap(close)))   
    printTable(message)
    alert(message, alert.freq_once_per_bar_close)



더 많은