Chiến lược giao dịch đảo chiều dựa trên hỗ trợ/kháng cự rộng


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

Chiến lược giao dịch đảo chiều dựa trên hỗ trợ/kháng cự rộng

Tổng quan

Chiến lược này dựa trên các chỉ số yếu tố nhiều không gian để thực hiện giao dịch đảo ngược, đồng thời thiết lập lợi ích mục tiêu. Cốt lõi của yếu tố nhiều không gian là hình thức mở rộng dựa trên khối lượng giao dịch.

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

  1. Xác định yếu tố hỗ trợ / kháng cự dựa trên số lượng giao dịch

    • Sử dụng hình dạng K-line để xác định hỗ trợ / kháng cự cổ điển, lọc phá vỡ giả mạo cho khối lượng giao dịch lớn hơn

    • Hỗ trợ / kháng cự khái quát có tính bao gồm tốt hơn so với hình thức cổ điển

    • Tiến phá định nghĩa rộng được hỗ trợ bởi tín hiệu đa yếu tố, vượt qua định nghĩa rộng được kháng cự bởi tín hiệu không yếu tố

  2. Giao dịch chuyển đổi

    • Sau khi phát ra tín hiệu nhân, thực hiện thao tác ngược

    • Nếu đã giữ vị thế, hãy giảm vị thế ngược hoặc mở vị thế ngược

  3. Đặt mục tiêu lợi nhuận

    • Thiết lập dừng lỗ theo ATR

    • Thiết lập nhiều mục tiêu như 1R/2R/3R có lợi

    • Cắt giảm hàng loạt sau khi đạt được mục tiêu lợi nhuận khác nhau

Phân tích lợi thế

  • Có thể bắt được sự đảo ngược lớn hơn trong ngắn hạn

Sự phá vỡ kháng cự hỗ trợ đại diện cho một tín hiệu đảo ngược xu hướng mạnh mẽ, có độ tin cậy nhất định, có thể bắt được sự đảo ngược lớn trong ngắn hạn.

  • Tạo lợi nhuận nhanh, rút tiền ít

Đặt mục tiêu dừng lỗ và lợi nhuận nhiều giai đoạn để đạt được lợi nhuận nhanh chóng và hạn chế việc rút cổ phiếu.

  • Đối với các chỉ số có nhiều quỹ tổ chức và biến động lớn

Chiến lược này phụ thuộc vào chỉ số khối lượng giao dịch, cần có đủ nguồn vốn của tổ chức để hỗ trợ xu hướng; đồng thời cần một số không gian dao động để tạo ra lợi nhuận.

Phân tích rủi ro

  • Rủi ro bị mắc kẹt trong tình trạng chấn động

Các hoạt động dừng lỗ, thoát ra và quay ngược vào thị trường có thể gây ra sự cố thường xuyên.

  • Rủi ro thất bại của kháng cự

Khả năng kháng cự hỗ trợ không hoàn toàn đáng tin cậy, có khả năng đảo ngược thử nghiệm thất bại.

  • Rủi ro của việc nắm giữ vị thế đơn phương

Chiến lược này hoàn toàn là đảo ngược, không tính đến việc theo dõi xu hướng và có thể bỏ lỡ cơ hội định hướng lớn hơn.

  • Kiểm soát gió

    • Các điều kiện yếu tố của giao dịch đảo ngược có thể được nới lỏng một cách thích hợp, không nhất thiết phải đảo ngược mỗi lần đột phá

    • Có thể kết hợp với các bộ lọc khác, chẳng hạn như giá lệch

    • Có thể tối ưu hóa chiến lược dừng lỗ để giảm khả năng bị mắc kẹt

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

  • Tối ưu hóa thông số caliber

Tối ưu hóa các tham số kháng cự hỗ trợ khái quát, xác định các yếu tố đáng tin cậy hơn

  • Tối ưu hóa chiến lược lợi nhuận

Bạn có thể thêm mục tiêu lợi nhuận ở nhiều cấp, hoặc có thể sử dụng mục tiêu lợi nhuận không cố định

  • Tối ưu hóa chiến lược dừng lỗ

Điều chỉnh tham số ATR hoặc sử dụng statistics để dừng lỗ, giảm chi phí giao dịch do dừng lỗ mạnh không cần thiết

  • Kết hợp xu hướng và các yếu tố khác

Có thể đưa ra phán đoán xu hướng như đường trung bình, tránh đối đầu nghiêm trọng với xu hướng; cũng có thể đưa ra các yếu tố hỗ trợ khác

Tóm tắt

Cốt lõi của chiến lược này là sử dụng giao dịch đảo ngược để nắm bắt sự biến động lớn trong ngắn hạn. Ý tưởng chiến lược đơn giản và trực tiếp, hiệu quả thực tế tốt có thể đạt được bằng cách điều chỉnh tham số. Tuy nhiên, chiến lược đảo ngược khá quyết liệt, có một số rủi ro rút lại và được đặt, cần tối ưu hóa thêm chiến lược dừng lỗ và lợi nhuận, và kết hợp hợp hợp với phán đoán xu hướng để giảm tổn thất không cần thiết.

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"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © DojiEmoji

//@version=5
strategy("Fractal Strat [KL] ", overlay=true, pyramiding=1, initial_capital=1000000000)
var string ENUM_LONG = "Long"
var string GROUP_ENTRY = "Entry"
var string GROUP_TSL = "Stop loss"
var string GROUP_TREND = "Trend prediction"
var string GROUP_ORDER = "Order size and Profit taking"

// backtest_timeframe_start = input.time(defval=timestamp("01 Apr 2000 13:30 +0000"), title="Backtest Start Time")
within_timeframe = true

// TSL: calculate the stop loss price. {
_multiple       = input(2.0, title="ATR Multiplier for trailing stop loss", group=GROUP_TSL)
ATR_TSL         = ta.atr(input(14, title="Length of ATR for trailing stop loss", group=GROUP_TSL, tooltip="Initial risk amount = atr(this length) x multiplier")) * _multiple
TSL_source      = low
TSL_line_color  = color.green
TSL_transp      = 100
var stop_loss_price = float(0)

var float initial_entry_p    = float(0)
var float risk_amt           = float(0)
var float initial_order_size = float(0)

if strategy.position_size == 0 or not within_timeframe
    TSL_line_color := color.black
    stop_loss_price := TSL_source - ATR_TSL
else if strategy.position_size > 0
    stop_loss_price := math.max(stop_loss_price, TSL_source - ATR_TSL)
    TSL_transp := 0

plot(stop_loss_price, color=color.new(TSL_line_color, TSL_transp))
// } end of "TSL" block


// Order size and profit taking {
pcnt_alloc = input.int(5, title="Allocation (%) of portfolio into this security", tooltip="Size of positions is based on this % of undrawn capital. This is fixed throughout the backtest period.", minval=0, maxval=100, group=GROUP_ORDER) / 100

// Taking profits at user defined target levels relative to risked amount (i.e 1R, 2R, 3R)
var bool  tp_mode = input(true, title="Take profit and different levels", group=GROUP_ORDER)
var float FIRST_LVL_PROFIT = input.float(1, title="First level profit", tooltip="Relative to risk. Example: entry at $10 and inital stop loss at $9. Taking first level profit at 1R means taking profits at $11", group=GROUP_ORDER)
var float SECOND_LVL_PROFIT = input.float(2, title="Second level profit", tooltip="Relative to risk. Example: entry at $10 and inital stop loss at $9. Taking second level profit at 2R means taking profits at $12", group=GROUP_ORDER)
var float THIRD_LVL_PROFIT = input.float(3, title="Third level profit", tooltip="Relative to risk. Example: entry at $10 and inital stop loss at $9. Taking third level profit at 3R means taking profits at $13", group=GROUP_ORDER)

// }

// Fractals {
// Modified from synapticEx's implementation: https://www.tradingview.com/script/cDCNneRP-Fractal-Support-Resistance-Fixed-Volume-2/

rel_vol_len = 6 // Relative volume is used; the middle candle has to have volume above the average (say sma over prior 6 bars)
rel_vol = ta.sma(volume, rel_vol_len)
_up = high[3]>high[4] and high[4]>high[5] and high[2]<high[3] and high[1]<high[2] and volume[3]>rel_vol[3]
_down = low[3]<low[4] and low[4]<low[5] and low[2]>low[3] and low[1]>low[2] and volume[3]>rel_vol[3]

fractal_resistance = high[3], fractal_support = low[3]   // initialize

fractal_resistance :=  _up ? high[3] : fractal_resistance[1]
fractal_support := _down ? low[3] : fractal_support[1]

plot(fractal_resistance, "fractal_resistance", color=color.new(color.red,50), linewidth=2, style=plot.style_cross, offset =-3, join=false)
plot(fractal_support, "fractal_support", color=color.new(color.lime,50), linewidth=2, style=plot.style_cross, offset=-3, join=false)
// }

// ATR diversion test {
// Hypothesis testing (2-tailed):
//
// Null hypothesis (H0) and Alternative hypothesis (Ha):
//     H0 : atr_fast equals atr_slow
//     Ha : atr_fast not equals to atr_slow; implies atr_fast is either too low or too high
len_fast    = input(5,title="Length of ATR (fast) for diversion test", group=GROUP_ENTRY)
atr_fast    = ta.atr(len_fast)
atr_slow    = ta.atr(input(50,title="Length of ATR (slow) for diversion test", group=GROUP_ENTRY, tooltip="This needs to be larger than Fast"))

// Calculate test statistic (test_stat)
std_error   = ta.stdev(ta.tr, len_fast) / math.pow(len_fast, 0.5)
test_stat = (atr_fast - atr_slow) / std_error

// Compare test_stat against critical value defined by user in settings
//critical_value = input.float(1.645,title="Critical value", tooltip="Strategy uses 2-tailed test to compare atr_fast vs atr_slow. Null hypothesis (H0) is that both should equal. Based on the computed test statistic value, if absolute value of it is +/- this critical value, then H0 will be rejected.", group=GROUP_ENTRY)
conf_interval = input.string(title="Confidence Interval", defval="95%", options=["90%","95%","99%"], tooltip="Critical values of 1.645, 1.96, 2.58, for CI=90%/95%/99%, respectively; Under 2-tailed test to compare atr_fast vs atr_slow. Null hypothesis (H0) is that both should equal. Based on the computed test statistic value, if absolute value of it is +/- critical value, then H0 will be rejected.")
critical_value = conf_interval == "90%" ? 1.645 : conf_interval == "95%" ? 1.96 : 2.58
reject_H0_lefttail = test_stat < -critical_value
reject_H0_righttail = test_stat > critical_value

// } end of "ATR diversion test" block

// Entry Signals
entry_signal_long = close >= fractal_support and reject_H0_lefttail

// MAIN {
// Update the stop limit if strategy holds a position.
if strategy.position_size > 0
    strategy.exit(ENUM_LONG, comment="SL", stop=stop_loss_price)

// Entry
if within_timeframe and entry_signal_long and strategy.position_size == 0
    initial_entry_p := close
    risk_amt := ATR_TSL
    initial_order_size := math.floor(pcnt_alloc * strategy.equity / close)
    strategy.entry(ENUM_LONG, strategy.long, qty=initial_order_size)

var int TP_taken_count = 0
if tp_mode and close > strategy.position_avg_price
    if close >= initial_entry_p + THIRD_LVL_PROFIT * risk_amt and TP_taken_count == 2
        strategy.close(ENUM_LONG, comment="TP Lvl3", qty=math.floor(initial_order_size / 3))
        TP_taken_count := TP_taken_count + 1
    else if close >= initial_entry_p + SECOND_LVL_PROFIT * risk_amt and TP_taken_count == 1
        strategy.close(ENUM_LONG, comment="TP Lvl2", qty=math.floor(initial_order_size / 3))
        TP_taken_count := TP_taken_count + 1
    else if close >= initial_entry_p + FIRST_LVL_PROFIT * risk_amt and TP_taken_count == 0
        strategy.close(ENUM_LONG, comment="TP Lvl1", qty=math.floor(initial_order_size / 3))
        TP_taken_count := TP_taken_count + 1
    
// Alerts
_atr = ta.atr(14)
alert_helper(msg) =>
    prefix = "[" + syminfo.root + "] "
    suffix = "(P=" + str.tostring(close, "#.##") + "; atr=" + str.tostring(_atr, "#.##") + ")"
    alert(str.tostring(prefix) + str.tostring(msg) + str.tostring(suffix), alert.freq_once_per_bar)

if strategy.position_size > 0 and ta.change(strategy.position_size)
    if strategy.position_size > strategy.position_size[1]
        alert_helper("BUY")
    else if strategy.position_size < strategy.position_size[1]
        alert_helper("SELL")

// Clean up - set the variables back to default values once no longer in use
if ta.change(strategy.position_size) and strategy.position_size == 0
    TP_taken_count := 0
    initial_entry_p := float(0)
    risk_amt := float(0)
    initial_order_size := float(0)
    stop_loss_price := float(0)
// } end of MAIN block