Chiến lược giao dịch mô hình Hammer and Shooting Star

Tác giả:ChaoZhang, Ngày: 2023-09-28 11:11:35
Tags:

Tổng quan

Chiến lược giao dịch này sử dụng các mô hình nến để dự đoán chuyển động giá trong tương lai. Đá và sao bắn là các mô hình đơn giản nhưng mạnh mẽ được sử dụng rộng rãi để bắt sự đảo ngược xu hướng. Chiến lược này xác định hai mô hình này để tận dụng các bước ngoặt trên thị trường.

Chiến lược logic

Chiến lược dựa trên các nguyên tắc cốt lõi sau:

  1. Chỉ số ATR lọc các thị trường không có xu hướng bằng cách yêu cầu kích thước nến nằm trong phạm vi các giá trị ATR.

  2. Mức khôi phục Fibonacci 33,3% đánh dấu điểm phân biệt một búa (khép bên trên) với một ngôi sao rơi (khép bên dưới).

  3. Xác nhận thêm yêu cầu mô hình hoàn thành (giá đóng trên / dưới giá mở) trên thanh chưa được xác nhận.

  4. Các mức dừng lỗ và lấy lợi nhuận được thiết lập dựa trên ATR và tỷ lệ rủi ro/lợi nhuận khi nhập.

Bằng cách kết hợp ATR, Fibonacci và nhận dạng mẫu, chiến lược tuân thủ các nguyên tắc chung của giao dịch xu hướng.

Phân tích lợi thế

Những lợi thế chính của chiến lược này là:

  1. Lý thuyết đơn giản làm cho nó dễ hiểu và thực hiện.

  2. Giao dịch theo các mô hình ngắn hạn trong ngày cho phép thời gian giữ linh hoạt.

  3. Bộ lọc ATR giúp kiểm soát rủi ro trong thị trường biến động. Các thông số có thể được tối ưu hóa riêng cho mỗi công cụ.

  4. Đặt lỗ thông minh và lấy điểm lợi nhuận dựa trên tỷ lệ rủi ro / phần thưởng kiểm soát rủi ro hiệu quả.

  5. Các tín hiệu giao dịch tự động hợp lý hóa việc nhập và quản lý vị trí.

  6. Áp dụng thị trường xuyên đối với nhiều cặp tiền tệ cho thấy sự vững chắc.

Phân tích rủi ro

Ngoài ra còn có một số rủi ro cần xem xét:

  1. Giao dịch mô hình có khả năng tín hiệu sai mà không nên tin tưởng mù quáng.

  2. Chi phí giao dịch như hoa hồng không được tính toán, ăn vào lợi nhuận thực tế.

  3. Tần suất giao dịch tăng từ giao dịch trong ngày ngắn có thể gây ra chi phí trượt cao hơn.

  4. Các thông số ATR tối ưu dựa trên dữ liệu lịch sử và có thể không phải lúc nào cũng được áp dụng.

  5. Rủi ro giao dịch tự động không thực hiện lệnh và nên thực hiện cơ chế thử lại.

  6. Các thiết lập dừng lỗ và lấy lợi nhuận kém có thể dẫn đến giao dịch quá mức hoặc để lại tiền trên bàn.

Cơ hội tối ưu hóa

Một số cách để cải thiện chiến lược:

  1. Các bộ lọc bổ sung như âm lượng để tăng hiệu quả mô hình.

  2. Kết hợp các khoản hoa hồng vào việc dừng và điều chỉnh mục tiêu.

  3. Tối ưu hóa các thông số ATR để phù hợp với các điều kiện thị trường thay đổi.

  4. Đánh giá hiệu suất của các thông số riêng biệt cho mỗi cặp tiền tệ.

  5. Thêm cơ chế tự động để giảm rủi ro thực hiện lệnh thất bại.

  6. Sử dụng các mô hình học máy để xác định tốt hơn các mẫu hợp lệ.

  7. Đưa ra một cơ chế dừng lại để khóa thêm lợi nhuận.

Kết luận

Tóm lại, chiến lược giao dịch này tích hợp các chỉ số kỹ thuật được sử dụng phổ biến với logic đơn giản để thực hiện đơn giản. Với tối ưu hóa tham số mạnh mẽ và kiểm soát rủi ro, nó có tiềm năng về lợi nhuận nhất quán. Tuy nhiên, các nhà giao dịch nên luôn cảnh giác với rủi ro và giữ tần suất giao dịch hợp lý để tránh giao dịch quá mức. Chiến lược này phục vụ như một khuôn khổ cơ bản cho sự đổi mới hơn nữa để đạt được mức hiệu suất giao dịch mới.


/*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")

Thêm nữa