Chiến lược đột phá trung bình động cấp cao


Ngày tạo: 2023-10-30 12:22:28 sửa đổi lần cuối: 2023-10-30 12:22:28
sao chép: 0 Số nhấp chuột: 659
1
tập trung vào
1617
Người theo dõi

Chiến lược đột phá trung bình động cấp cao

Tổng quan

Ý tưởng chính của chiến lược này là sử dụng phá vỡ đường trung bình cấp cao để thực hiện giao dịch xu hướng. Trong phạm vi thời gian cấp cao, khi giá phá vỡ đường trung bình lên hoặc xuống, bạn có thể xác định được sự bắt đầu của xu hướng, khi đó bạn có thể chọn hướng thích hợp để theo dõi.

Nguyên tắc chiến lược

Chiến lược này được phát triển bằng ngôn ngữ Pine Script và bao gồm các phần sau:

  1. Các tham số đầu vào

Định nghĩa tham số chu kỳ trung bình là period, giá trị mặc định là 200; định nghĩa tham số chu kỳ thời gian K-line là timeframe, giá trị mặc định là ngày “D”.

  1. Tính trung bình

Sử dụng hàm ta.ema để tính toán đường trung bình di chuyển theo cấp số nhân.

  1. Bước đột phá

Sử dụng các hàm ta.crossover và ta.crossunder để xác định xem giá có phá vỡ hoặc phá vỡ đường trung bình hay không.

  1. Hình ảnh tín hiệu

Khi có đột phá, vẽ mũi tên lên hoặc xuống trên đường K.

  1. Giao dịch mở lỗ

Khi có đột phá, chọn hướng mở vị trí và thanh toán sau khi đạt được khoảng cách dừng gấp đôi.

Chiến lược này dựa chủ yếu vào khả năng phân định xu hướng của đường trung bình cấp cao, theo dõi xu hướng thông qua các hoạt động đột phá đơn giản, thuộc về chiến lược đột phá truyền thống hơn.

Phân tích lợi thế

Chiến lược này có một số ưu điểm:

  1. Khái niệm đơn giản, dễ hiểu và nắm bắt.

  2. Điều chỉnh tham số đơn giản chỉ dựa trên chỉ số đường trung bình.

  3. Các hoạt động đột phá dễ tạo xu hướng và không giao dịch thường xuyên.

  4. Chu kỳ cấp cao cho thấy xu hướng lớn và không dễ bị ảnh hưởng bởi biến động ngắn hạn.

  5. Có thể cấu hình các kết hợp chu kỳ thời gian khác nhau, phù hợp với các giống khác nhau.

  6. Có thể dễ dàng theo dõi nhiều giống và khó bị nhốt cùng một lúc.

Phân tích rủi ro

Chiến lược này cũng có một số rủi ro:

  1. Các tín hiệu phá vỡ có thể xảy ra phá vỡ giả, không có khả năng lọc hiệu quả sự biến động của thị trường.

  2. Không thể tận dụng các cơ hội ngắn gọn để kiếm lợi nhuận.

  3. Những người này có thể bị thiệt hại nặng nề hơn khi họ đánh giá sai.

  4. Khi chu kỳ đường trung bình và chu kỳ giao dịch không phù hợp, có thể xảy ra giao dịch quá mức hoặc lỗ hổng.

  5. Không thể dừng lỗ trong thời gian thực và có khả năng tăng lỗ.

Các giải pháp đối phó với rủi ro bao gồm: kết hợp các chỉ số xu hướng, tăng điều kiện lọc, rút ngắn thời gian giữ vị trí thích hợp, điều chỉnh động vị trí dừng lỗ.

Hướng tối ưu hóa

Chiến lược này có thể được tối ưu hóa theo các khía cạnh sau:

  1. Tăng sự kết hợp của các chỉ số xu hướng, như MACD, KD, để tăng độ tin cậy đột phá.

  2. Tăng các điều kiện lọc như khối lượng giao dịch hoặc kênh Brinline để tránh phá vỡ giả.

  3. Tối ưu hóa các tham số phù hợp với chu kỳ, làm cho chu kỳ giữ vị thế phù hợp hơn với chu kỳ xu hướng.

  4. Thêm chiến lược dừng lỗ theo thời gian thực để kiểm soát tổn thất đơn lẻ bằng cách theo dõi dừng lỗ

  5. Xem xét tối ưu hóa động của các tham số kết hợp với công nghệ học máy.

  6. Thử nhiều loại danh mục tài sản khác nhau để tăng sự ổn định tổng thể.

Tóm tắt

Chiến lược này nói chung là đơn giản và thực tế, theo dõi xu hướng bằng cách phá vỡ đường đồng nhất đơn giản, dễ nắm bắt, có thể là một trong những chiến lược nhập cảnh của giao dịch định lượng. Tuy nhiên, cũng có một số vấn đề cần được cải thiện bằng cách sử dụng chỉ số kết hợp, tham số tối ưu hóa, dừng lỗ động, để làm cho chiến lược ổn định và hiệu quả hơn. Có nhiều không gian tối ưu hóa và khả năng mở rộng.

Mã nguồn chiến lược
/*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)