형태 예측 전략은 그래프 형태를 사용하여 미래의 가격 움직임을 판단하는 것으로 거래계에서 널리 사용된다. 이 전략은 두 가지 간단한 형태를 식별하여 트렌드 반전의 기회를 잡는다.
이 전략은 다음과 같은 원칙에 기초하고 있습니다.
ATR 지표를 사용하여 강하고 약한 트렌드를 식별하고, 흔들리는 시장을 필터링하십시오. ATR 값이 설정된 최소 절벽보다 작거나 최대 절벽보다 크면 거래가 고려됩니다.
현재 K선에서 33.3%의 피보나치 리트랙 라인을 계산한다. 이 라인을 상회하면 ?? 라인, 이 라인을 상회하면 슈팅 스타로 간주한다.
확인된 형태에 대해 추가 확인을 하고, 형태를 완료하도록 요구한다 (개체 부분이 상점 가격보다 높거나 낮다), 그리고 확인되지 않은 K선이다.
진입 후 중지 및 중지 설정, 중지 ATR의 일정한 배수, 중지 중지의 위험 수익 배수.
이 전략은 ATR 지표와 피보나치 기술을 사용하여 수선과 쏘아 올린 별의 형태를 인식하고, 위험 제어 지표를 설정하며, 트렌드 거래의 일반적인 원칙에 부합한다.
이 전략은 다음과 같은 장점을 가지고 있습니다.
그리고 이 아이디어는 매우 간단하고, 이해하기 쉽고, 실행이 가능합니다.
하루 단기 형태를 이용해서, 긴 시간을 기다리지 않고, 유연한 자세로 포지션을 보유할 수 있다.
ATR 매개 변수 설정은 과대행동의 위험을 제어한다. 다양한 품종에 대해 개별적으로 최적화 매개 변수 수 있다.
리스크와 수익률에 합리적 스톱 스톱 손실을 설정하면 위험을 조절할 수 있다.
자동화 거래 신호는 직접적으로 연계되어 있으며, 조작이 간단하다.
여러 품종에 적용 가능하며, 보편성이 있다.
이 전략에는 몇 가지 위험도 있습니다.
형식 거래는 잘못된 판단의 비율이 있기 때문에 전적으로 의존할 수 없습니다.
거래 수수료를 고려하지 않고 실제 수익을 얻을 수 있는 공간이 더 작습니다.
하루 단편 거래는 거래 빈도와 슬라이드 포인트 비용을 증가시킬 수 있습니다.
ATR 파라미터를 최적화하는 것은 역사 데이터에 의존하고, 파라미터가 항상 적용될 수 있다는 것을 보장할 수 없다.
자동 주문은 발송 실패의 위험이 있으며, 재시험 메커니즘을 설정해야 한다.
잘못된 스톱더스 설정은 과잉 또는 과소 인수를 유발할 수 있습니다.
이 전략은 다음과 같은 방향으로 최적화를 고려할 수 있습니다.
다른 필터링 조건을 추가하여 거래량과 형식 효율성을 향상시킵니다.
수수료 설정을 고려하고, 정지지 지점을 최적화하십시오.
동적으로 ATR 변수를 최적화하여 다른 상황주기에 적합하도록 한다.
거래 품종 쌍의 매개 변수를 평가하고 개인화 매개 변수를 설정합니다.
자동 재시험 메커니즘을 늘리고, 단독 위험을 낮춰야 한다.
기계 학습을 통해 형상 인식의 정확도를 향상시킵니다.
더 많은 수익을 올릴 수 있도록 스톱로스 추적을 추가합니다.
요약하자면, 이 거래 전략은 일반적으로 사용되는 기술 지표와 원리를 통합하여 이해하기 쉽고 실행할 수 있습니다. 매개 변수 최적화 및 위험 통제가 이루어지면 안정적인 수익을 얻을 수 있습니다. 그러나 거래자는 여전히 위험을 조심하고 거래 수를 적당히 유지하며 과도한 급진주의를 피해야합니다. 이 전략은 기초형 전략으로, 그 기초를 기반으로 확장 혁신을 수행하여 거래 효과를 새로운 수준으로 향상시킬 수 있습니다.
/*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")