해머와 슈팅 스타 패턴 거래 전략

저자:차오장, 날짜: 2023-09-28 11:11:35
태그:

전반적인 설명

이 거래 전략은 미래의 가격 움직임을 예측하기 위해 촛불 패턴을 사용합니다. 해머와 쏘닝 스타는 트렌드 반전을 잡기 위해 널리 사용되는 간단하지만 강력한 패턴입니다. 이 전략은 시장의 전환점을 활용하기 위해 이 두 패턴을 식별합니다.

전략 논리

이 전략은 다음의 핵심 원칙에 기초합니다.

  1. ATR 지표는 촛불 크기가 ATR 값의 설정 범위 내에 있어야 한다는 것을 요구함으로써 트렌드가 아닌 시장을 필터링합니다.

  2. 33.3% 피보나치 리트레이스먼트 레벨은 해머 (위쪽에서 닫는다) 와 저쪽에서 닫는다 (아래쪽에서 닫는다) 를 구별하는 지점을 나타냅니다.

  3. 추가 확인은 확인되지 않은 바에서 패턴이 완료되도록 요구합니다.

  4. 스톱 로즈와 영업 영업 레벨은 ATR 및 입시에 위험/이익 비율에 따라 설정됩니다.

ATR, 피보나치 및 패턴 인식을 결합함으로써 전략은 트렌드 거래의 일반적인 원칙을 준수합니다.

이점 분석

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

  1. 간단한 논리는 이해하기 쉽고 실행하기 쉽다.

  2. 단기 내일 패턴의 거래는 유연한 보유 기간을 허용합니다.

  3. ATR 필터는 변동성 시장에서 위험을 제어하는 데 도움이됩니다. 매개 계기별로 매개 변수를 최적화 할 수 있습니다.

  4. 지능적인 스톱 로스 및 수익 포인트는 리스크/어워드 비율을 바탕으로 효과적으로 리스크를 제어합니다.

  5. 자동화 된 거래 신호는 진입 및 위치 관리를 효율화합니다.

  6. 많은 통화 쌍에 적용되는 크로스 마켓은 안정성을 보여줍니다.

위험 분석

또한 고려해야 할 몇 가지 위험이 있습니다.

  1. 패턴 거래는 맹목적으로 신뢰해서는 안되는 잘못된 신호의 가능성이 있습니다.

  2. 수수료와 같은 거래 비용은 계산되지 않고 실제 수익을 잡아먹습니다.

  3. 단기 내일 거래에서 거래 빈도가 증가하면 더 많은 미끄러짐 비용이 발생할 수 있습니다.

  4. 최적화된 ATR 매개 변수는 역사적 데이터에 의존하고 항상 적용되지 않을 수 있습니다.

  5. 자동 거래 위험은 주문 실행에 실패하여 재시작 메커니즘을 구현해야합니다.

  6. 잘못된 스톱 로즈와 수익 취득 설정은 과도한 거래로 이어질 수 있습니다. 또는 테이블에 돈을 남길 수 있습니다.

최적화 기회

전략을 개선할 수 있는 몇 가지 방법:

  1. 패턴의 효과를 높이기 위해 부피와 같은 추가 필터.

  2. 스톱과 타겟 조정에 수수료를 포함합니다.

  3. 변화하는 시장 조건에 맞게 ATR 매개 변수를 동적으로 최적화합니다.

  4. 각 통화 쌍의 매개 변수 성능을 개별적으로 평가합니다.

  5. 자동 검색 메커니즘을 추가하여 오더 실행 실패 위험을 줄이십시오.

  6. 유효한 패턴을 더 잘 식별하기 위해 기계 학습 모델을 활용합니다.

  7. 더 많은 수익을 확보하기 위해 후속 정지 메커니즘을 도입해야 합니다.

결론

요약하자면,이 거래 전략은 간편한 구현을 위해 일반적으로 사용되는 기술적 지표를 간단한 논리로 통합합니다. 강력한 매개 변수 최적화 및 위험 통제로 인해 일관된 수익성을 얻을 수 있습니다. 그러나 거래자는 위험을 경계하고 과도한 거래를 피하기 위해 거래 주파수를 합리적으로 유지해야합니다. 전략은 새로운 수준의 거래 성과를 달성하기 위해 추가 혁신을위한 기본 프레임워크로 사용됩니다.


/*backtest
start: 2023-08-28 00:00:00
end: 2023-09-27 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/
// © ZenAndTheArtOfTrading / PineScriptMastery
// Last Updated: 28th April, 2021
// @version=4
strategy("Hammers & Stars Strategy [v1.0]", shorttitle="HSS[v1.0]", overlay=true)

// Get user input
atrMinFilterSize = input(title=">= ATR Filter", type=input.float, defval=0.0, minval=0.0, tooltip="Minimum size of entry candle compared to ATR", group="Strategy Settings")
atrMaxFilterSize = input(title="<= ATR Filter", type=input.float, defval=3.0, minval=0.0, tooltip="Maximum size of entry candle compared to ATR", group="Strategy Settings")
stopMultiplier   = input(title="Stop Loss ATR", type=input.float, defval=1.0, tooltip="Stop loss multiplier (x ATR)", group="Strategy Settings")
rr               = input(title="R:R", type=input.float, defval=1.0, tooltip="Risk:Reward profile", group="Strategy Settings")
fibLevel         = input(title="Fib Level", type=input.float, defval=0.333, tooltip="Used to calculate upper/lower third of candle. (For example, setting it to 0.5 will mean hammers must close >= 50% mark of the total candle size)", group="Strategy Settings")
i_startTime      = input(title="Start Date Filter", defval=timestamp("01 Jan 2000 13:30 +0000"), type=input.time, tooltip="Date & time to begin trading from", group="Strategy Settings")
i_endTime        = input(title="End Date Filter", defval=timestamp("1 Jan 2099 19:30 +0000"), type=input.time, tooltip="Date & time to stop trading", group="Strategy Settings")
oandaDemo        = input(title="Use Oanda Demo?", type=input.bool, defval=false, tooltip="If turned on then oandapractice broker prefix will be used for AutoView alerts (demo account). If turned off then live account will be used", group="AutoView Oanda Settings")
limitOrder       = input(title="Use Limit Order?", type=input.bool, defval=true, tooltip="If turned on then AutoView will use limit orders. If turned off then market orders will be used", group="AutoView Oanda Settings")
gtdOrder         = input(title="Days To Leave Limit Order", type=input.integer, minval=0, defval=2, tooltip="This is your GTD setting (good til day)", group="AutoView Oanda Settings")
accountBalance   = input(title="Account Balance", type=input.float, defval=1000.0, step=100, tooltip="Your account balance (used for calculating position size)", group="AutoView Oanda Settings")
accountCurrency  = input(title="Account Currency", type=input.string, defval="USD", options=["AUD", "CAD", "CHF", "EUR", "GBP", "JPY", "NZD", "USD"], tooltip="Your account balance currency (used for calculating position size)", group="AutoView Oanda Settings")
riskPerTrade     = input(title="Risk Per Trade %", type=input.float, defval=2.0, step=0.5, tooltip="Your risk per trade as a % of your account balance", group="AutoView Oanda Settings")

// Set up AutoView broker prefix
var broker = oandaDemo ? "oandapractice" : "oanda"

// See if this bar's time happened within date filter
dateFilter = true

// Get ATR
atr = atr(14)

// Check ATR filter
atrMinFilter = abs(high - low) >= (atrMinFilterSize * atr) or atrMinFilterSize == 0.0
atrMaxFilter = abs(high - low) <= (atrMaxFilterSize * atr) or atrMaxFilterSize == 0.0
atrFilter = atrMinFilter and atrMaxFilter

// Calculate 33.3% fibonacci level for current candle
bullFib = (low - high) * fibLevel + high
bearFib = (high - low) * fibLevel + low

// Determine which price source closes or opens highest/lowest
lowestBody = close < open ? close : open
highestBody = close > open ? close : open

// Determine if we have a valid setup
validHammer = lowestBody >= bullFib and atrFilter and close != open and not na(atr)
validStar = highestBody <= bearFib and atrFilter and close != open and not na(atr)

// Check if we have confirmation for our setup
validLong = validHammer and strategy.position_size == 0 and dateFilter and barstate.isconfirmed
validShort = validStar and strategy.position_size == 0 and dateFilter and barstate.isconfirmed

//------------- DETERMINE POSITION SIZE -------------//
// Get account inputs
var tradePositionSize = 0.0
var pair = syminfo.basecurrency + "/" + syminfo.currency

// Check if our account currency is the same as the base or quote currency (for risk $ conversion purposes)
accountSameAsCounterCurrency = accountCurrency == syminfo.currency
accountSameAsBaseCurrency = accountCurrency == syminfo.basecurrency

// Check if our account currency is neither the base or quote currency (for risk $ conversion purposes)
accountNeitherCurrency = not accountSameAsCounterCurrency and not accountSameAsBaseCurrency

// Get currency conversion rates if applicable
conversionCurrencyPair = accountSameAsCounterCurrency ? syminfo.tickerid : accountNeitherCurrency ? accountCurrency + syminfo.currency : accountCurrency + syminfo.currency
conversionCurrencyRate = security(symbol=syminfo.type == "forex" ? "BTC_USDT:swap" : "BTC_USDT:swap", resolution="D", expression=close)

// Calculate position size
getPositionSize(stopLossSizePoints) =>
    riskAmount = (accountBalance * (riskPerTrade / 100)) * (accountSameAsBaseCurrency or accountNeitherCurrency ? conversionCurrencyRate : 1.0)
    riskPerPoint = (stopLossSizePoints * syminfo.pointvalue)
    positionSize = (riskAmount / riskPerPoint) / syminfo.mintick
    round(positionSize)
    
// Custom function to convert pips into whole numbers
toWhole(number) =>
    return = atr(14) < 1.0 ? (number / syminfo.mintick) / (10 / syminfo.pointvalue) : number
    return := atr(14) >= 1.0 and atr(14) < 100.0 and syminfo.currency == "JPY" ? return * 100 : return
//------------- END POSITION SIZE CODE -------------//

// Calculate our stop distance & size for the current bar
stopSize = atr * stopMultiplier
longStopPrice = low < low[1] ? low - stopSize : low[1] - stopSize
longStopDistance = close - longStopPrice
longTargetPrice = close + (longStopDistance * rr)
shortStopPrice = high > high[1] ? high + stopSize : high[1] + stopSize
shortStopDistance = shortStopPrice - close
shortTargetPrice = close - (shortStopDistance * rr)

// Save trade stop & target & position size if a valid setup is detected
var tradeStopPrice = 0.0
var tradeTargetPrice = 0.0

// Set up our GTD (good-til-day) order info
gtdTime = time + (gtdOrder * 1440 * 60 * 1000) // 86,400,000ms per day
gtdYear = year(gtdTime)
gtdMonth = month(gtdTime)
gtdDay = dayofmonth(gtdTime)
gtdString = " dt=" + tostring(gtdYear) + "-" + tostring(gtdMonth) + "-" + tostring(gtdDay)

// Detect valid long setups & trigger alert
if validLong
    tradeStopPrice := longStopPrice
    tradeTargetPrice := longTargetPrice
    tradePositionSize := getPositionSize(toWhole(longStopDistance) * 10)
    // Trigger AutoView long alert
    alert(message="e=" + broker + " b=long q="
     + tostring(tradePositionSize) 
     + " s=" + pair
     + " t=" + (limitOrder ? "limit fp=" + tostring(close) : "market")
     + " fsl=" + tostring(tradeStopPrice)
     + " ftp=" + tostring(tradeTargetPrice)
     + (gtdOrder != 0 and limitOrder ? gtdString : ""), 
     freq=alert.freq_once_per_bar_close)
   
// Detect valid short setups & trigger alert
if validShort
    tradeStopPrice := shortStopPrice
    tradeTargetPrice := shortTargetPrice
    tradePositionSize := getPositionSize(toWhole(shortStopDistance) * 10)
    // Trigger AutoView short alert
    alert(message="e=" + broker + " b=short q="
     + tostring(tradePositionSize)
     + " s=" + pair
     + " t=" + (limitOrder ? "limit fp=" + tostring(close) : "market")
     + " fsl=" + tostring(tradeStopPrice)
     + " ftp=" + tostring(tradeTargetPrice)
     + (gtdOrder != 0 and limitOrder ? gtdString : ""),
     freq=alert.freq_once_per_bar_close)

// Enter trades whenever a valid setup is detected
strategy.entry(id="Long", long=strategy.long, when=validLong)
strategy.entry(id="Short", long=strategy.short, when=validShort)

// Exit trades whenever our stop or target is hit
strategy.exit(id="Long Exit", from_entry="Long", limit=tradeTargetPrice, stop=tradeStopPrice, when=strategy.position_size > 0)
strategy.exit(id="Short Exit", from_entry="Short", limit=tradeTargetPrice, stop=tradeStopPrice, when=strategy.position_size < 0)

// Draw trade data
plot(strategy.position_size != 0 or validLong or validShort ? tradeStopPrice : na, title="Trade Stop Price", color=color.red, style=plot.style_linebr, transp=0)
plot(strategy.position_size != 0 or validLong or validShort ? tradeTargetPrice : na, title="Trade Target Price", color=color.green, style=plot.style_linebr, transp=0)
plot(strategy.position_size != 0 or validLong or validShort ? tradePositionSize : na, color=color.purple, transp=100, title="AutoView Position Size")

// Draw price action setup arrows
plotshape(validLong ? 1 : na, style=shape.triangleup, location=location.belowbar, color=color.green, title="Bullish Setup")
plotshape(validShort ? 1 : na, style=shape.triangledown, location=location.abovebar, color=color.red, title="Bearish Setup")

더 많은