Chiến lược đảo ngược trung bình dựa trên ATR

Tác giả:ChaoZhang, Ngày: 2023-10-17 16:27:44
Tags:

img

Tổng quan

Chiến lược này sử dụng thử nghiệm giả thuyết để xác định xem ATR có sai lệch so với giá trị trung bình của nó hay không. Kết hợp với dự đoán xu hướng giá, nó thực hiện một chiến lược đảo ngược trung bình dựa trên ATR. Sự lệch đáng kể của ATR chỉ ra sự biến động bất thường tiềm ẩn trên thị trường. Nếu xu hướng giá được dự đoán sẽ tăng, một vị trí dài có thể được thiết lập.

Chiến lược logic

  1. Kiểm tra giả thuyết

    • Thực hiện thử nghiệm t hai mẫu giữa thời gian ATR nhanh (atr_fast) và thời gian ATR chậm (atr_slow). giả thuyết không H0 là không có sự khác biệt đáng kể giữa hai trung bình mẫu.

    • Nếu số liệu thống kê thử nghiệm vượt quá ngưỡng (phạm vi độ tin cậy được chỉ định bởi yếu tố độ tin cậy), từ chối giả thuyết không, tức là ATR nhanh được coi là lệch đáng kể so với ATR chậm.

  2. Dự đoán xu hướng giá

    • Trung bình động của lợi nhuận logaritm được tính theo tỷ lệ trôi dạt dự kiến (trôi dạt).

    • Nếu xu hướng đang gia tăng, xu hướng hiện tại được đánh giá là tăng.

  3. Mở cửa và dừng lỗ

    • Đi dài khi ATR nhanh và chậm khác nhau đáng kể và xu hướng tăng.

    • Tiếp tục điều chỉnh dừng lỗ bằng cách sử dụng ATR. Đi khỏi vị trí khi giá phá vỡ dưới mức dừng lỗ.

Phân tích lợi thế

  • Sử dụng thử nghiệm giả thuyết để xác định độ lệch ATR là khoa học và thích nghi hơn.

  • Kết hợp với dự đoán xu hướng giá tránh các giao dịch sai chỉ dựa trên độ lệch ATR.

  • Điều chỉnh dừng lỗ liên tục quản lý rủi ro giảm.

Phân tích rủi ro

  • Không thể ngăn chặn tổn thất khi giá giảm.

  • Dự đoán xu hướng không chính xác có thể dẫn đến mua ở trên cùng.

  • Cài đặt tham số không chính xác có thể không nhập chính xác hoặc thêm các giao dịch không cần thiết.

Các đề xuất tối ưu hóa

  • Xem xét thêm các chỉ số khác để xác nhận nhiều yếu tố để tránh sai lầm.

  • Kiểm tra các kết hợp tham số ATR khác nhau để tìm ra các giá trị ổn định hơn.

  • Thêm các tiêu chí về đột phá các mức giá chính để tránh đột phá sai.

Kết luận

Các quy tắc dừng lỗ là đáng tin cậy nhưng không hiệu quả chống lại các vụ tai nạn theo kiểu vách đá. Những cải tiến trong tương lai có thể được thực hiện trong các lĩnh vực như tiêu chí nhập cảnh, lựa chọn tham số, tối ưu hóa dừng lỗ.


/*backtest
start: 2022-10-16 00:00:00
end: 2023-10-16 00:00:00
period: 1d
basePeriod: 1h
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("Mean Reversion (ATR) Strategy v2 [KL] ", overlay=true, pyramiding=1)
var string ENUM_LONG = "Long"
var string GROUP_TEST = "Hypothesis testing"
var string GROUP_TSL = "Stop loss"
var string GROUP_TREND = "Trend prediction"

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

// TSL: calculate the stop loss price. {
ATR_TSL      = ta.atr(input(14, title="Length of ATR for trailing stop loss", group=GROUP_TSL)) * input(2.0, title="ATR Multiplier for trailing stop loss", group=GROUP_TSL)
TSL_source      = low
TSL_line_color  = color.green
TSL_transp      = 100
var stop_loss_price = 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

// Entry variables {
// ATR diversion test via Hypothesis testing (2-tailed):
//     H0 : atr_fast equals atr_slow
//     Ha : reject H0 if z_stat is above critical value, say reliability factor of 1.96 for a 95% confidence interval
len_fast    = input(14,title="Length of ATR (fast) for diversion test", group=GROUP_TEST)
atr_fast    = ta.atr(len_fast)
std_error   = ta.stdev(ta.tr, len_fast) / math.pow(len_fast, 0.5) // Standard Error (SE) = std / sq root(sample size)

atr_slow = ta.atr(input(28,title="Length of ATR (slow) for diversion test", group=GROUP_TEST))
test_stat = (atr_fast - atr_slow) / std_error
reject_H0 = math.abs(test_stat) > input.float(1.645,title="Reliability factor", tooltip="Strategy uses 2-tailed test; Confidence Interval = Point Estimate (avg ATR) +/- Reliability Factor x Standard Error; i.e use 1.645 for a 90% confidence interval", group=GROUP_TEST)

// main entry signal, subject to confirmation(s), gets passed onto the next bar
var _signal_diverted_ATR = false
if not _signal_diverted_ATR
    _signal_diverted_ATR := reject_H0


// confirmation: trend prediction; based on expected lognormal returns
_prcntge_chng = math.log(close / close[1]) 

// Expected return (drift) = average percentage change + half variance over the lookback period
len_drift = input(14, title="Length of drift", group=GROUP_TREND)
_drift = ta.sma(_prcntge_chng, len_drift) - math.pow(ta.stdev(_prcntge_chng, len_drift), 2) * 0.5
_signal_uptrend = _drift > _drift[1]

entry_signal_all = _signal_diverted_ATR and _signal_uptrend // main signal + confirmations
// } end of "Entry variables" block

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

// Entry
if within_timeframe and entry_signal_all
    strategy.entry(ENUM_LONG, strategy.long, comment=strategy.position_size > 0 ? "adding" : "initial")

// 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 strategy.position_size == 0
    stop_loss_price := float(0)
if ta.change(strategy.position_size)
    _signal_diverted_ATR := false
// } end of MAIN block

Thêm nữa