고수준 이동평균 돌파 전략


생성 날짜: 2023-10-30 12:22:28 마지막으로 수정됨: 2023-10-30 12:22:28
복사: 0 클릭수: 659
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

고수준 이동평균 돌파 전략

개요

이 전략의 주요 아이디어는 상위 레벨 평균선의 돌파구를 사용하여 트렌드 거래를 구현하는 것이다. 상위 레벨 시간 범위에서 가격이 상위 또는 하위 평균선을 돌파할 때, 트렌드의 시작을 판단할 수 있으며, 이 때 적절한 방향을 선택하여 추적할 수 있다.

전략 원칙

이 전략은 Pine Script 언어로 개발되었으며, 다음과 같은 부분으로 구성되어 있습니다.

  1. 입력 변수

평균선 주기 변수 period가 정의되어 있고, 기본값은 200이다. K선 시간 주기 변수 timeframe가 정의되어 있으며, 기본값은 일선 “D”이다.

  1. 평균선 계산

ta.ema 함수를 사용하여 Exponential Moving Average 평균선을 계산한다.

  1. 판별의 돌파구

ta.crossover 및 ta.crossunder 함수를 사용하여 가격이 평균선을 돌파하거나 돌파하는지 판단하십시오.

  1. 신호 그리기

돌파구가 발생했을 때 K선에서 위 또는 아래로 화살표를 그리십시오.

  1. 거래는 공평하다

돌파가 발생했을 때 선택적인 방향으로 포즈를 개시하고, 이중 스톱로즈 거리가 도달한 후 평형 포지션.

이 전략은 주로 고위 수준의 평균 선의 경향 판단 능력을 의존하며, 간단한 돌파구 동작을 통해 트렌드 추적을 구현한다.

우위 분석

이 전략에는 다음과 같은 장점이 있습니다.

  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)