Tài nguyên đang được tải lên... tải...

Chiến lược xu hướng ATR đảo ngược trung bình

Tác giả:ChaoZhang, Ngày: 2023-09-21 11:42:06
Tags:

Tổng quan

Chiến lược này sử dụng mức cao và thấp của biến động giá để xác định thời gian nhập và ra khỏi các vị trí. Nó nhằm mục đích thiết lập các vị trí dài khi biến động giá cao và kiếm lợi nhuận khi xu hướng giá thuận lợi.

Chiến lược logic

  1. Sử dụng chỉ số ATR để đo biến động giá. Tính toán ATR trong 20 giai đoạn qua và lấy trung bình động và độ lệch chuẩn của nó. Nếu giá trị ATR hiện tại vượt quá mức trung bình cộng với một độ lệch chuẩn, biến động giá được coi là cao.

  2. Sử dụng tỷ lệ thay đổi giá theo thuật toán thứ nhất để xác định xu hướng giá. Tính toán tỷ lệ thay đổi giá gần theo thuật toán trong 20 giai đoạn qua, lấy trung bình động của nó. Nếu tỷ lệ thay đổi hiện tại vượt quá mức trung bình trong 3 ngày liên tiếp và dương tính, giá được coi là xu hướng tăng.

  3. Khi biến động giá cao và giá cho thấy xu hướng tăng, đi dài. Khi giá kéo trở lại và dừng lỗ được kích hoạt, đóng vị trí. Giá dừng lỗ được điều chỉnh năng động để ở dưới giá thấp nhất trừ 2 lần ATR.

Phân tích lợi thế

  1. Sử dụng biến động giá và xu hướng để xác định thời gian dài / ngắn, tránh giao dịch quá mức trong các thị trường khác nhau.

  2. Động lực dừng lỗ tránh mất quá nhiều từ dừng quá rộng.

  3. Kiểm tra lại cho thấy lợi nhuận hàng năm là 159% trong giai đoạn 2015-2021, vượt xa 120% của mua và giữ.

Phân tích rủi ro

  1. Các thông số ATR quá hung hăng có thể dẫn đến quá ít cơ hội nhập cảnh. Có thể thư giãn các thông số một cách vừa phải để tăng tần số.

  2. Chỉ số xu hướng có thể tạo ra các tín hiệu sai trái trái với xu hướng thực tế.

  3. Thời gian thử nghiệm chỉ 6 năm. cần mẫu lớn hơn và kiểm tra độ bền để tránh quá phù hợp.

  4. Không thể đánh giá hiệu suất trong điều kiện cực đoan như flash crash.

Hướng dẫn tối ưu hóa

  1. Thêm nhiều chỉ số xác nhận xu hướng như MACD, KDJ để cải thiện độ chính xác xu hướng.

  2. Điều chỉnh các thông số ATR thích nghi dựa trên các sản phẩm và chế độ thị trường khác nhau để tối ưu hóa chỉ số biến động.

  3. Thêm logic đột phá và các yếu tố tăng tốc xu hướng để đánh giá các đột phá.

  4. Kiểm tra các loại dừng lỗ khác nhau như tỷ lệ phần trăm, dừng biến động trên hiệu suất.

  5. Đánh giá trên các chỉ số như tần suất giao dịch, ổn định đường cong, rút tối đa để đảm bảo độ bền.

Tóm lại

Chiến lược này kết hợp các lợi thế của việc đo lường biến động và xu hướng để xác định các điểm đảo ngược có thể tham gia vào biến động khuếch đại, và sử dụng các điểm dừng động để kiểm soát rủi ro. Backtest cho thấy alpha được tạo ra tốt. Nhưng mẫu 6 năm có giới hạn, các thông số chính cần điều chỉnh cụ thể trên thị trường và cần nhiều yếu tố xác nhận hơn để giảm tín hiệu sai. Kiểm tra độ bền toàn diện cũng cần thiết trước khi áp dụng cho giao dịch trực tiếp. Nhìn chung, điều này cung cấp một ý tưởng về sự đảo ngược trung bình về biến động nhưng vẫn cần tinh chỉnh và xác minh nghiêm ngặt để trở thành một chiến lược lượng lớn mạnh mẽ.


/*backtest
start: 2022-09-14 00:00:00
end: 2023-09-20 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 (kevinhhl)

//@version=4
strategy("Mean Reversion (ATR) Strategy [KL]",overlay=true,pyramiding=1)
ENUM_LONG = "Long"

// Timeframe {
backtest_timeframe_start = input(defval = timestamp("01 Apr 2000 13:30 +0000"), title = "Backtest Start Time", type = input.time)
USE_ENDTIME = input(false,title="Define backtest end-time (If false, will test up to most recent candle)")
backtest_timeframe_end = input(defval = timestamp("01 May 2021 19:30 +0000"), title = "Backtest End Time (if checked above)", type = input.time)
within_timeframe = true
// }

// Trailing stop loss {
ATR_X2_TSL = atr(input(14,title="Length of ATR for trailing stop loss")) * input(2.0,title="ATR Multiplier for trailing stop loss",type=input.float)
TSL_source = low
var stop_loss_price = float(0)
TSL_line_color = color.green, TSL_transp = 100
if strategy.position_size == 0 or not within_timeframe
    TSL_line_color := color.black
    stop_loss_price := TSL_source - ATR_X2_TSL 
else if strategy.position_size > 0
    stop_loss_price := max(stop_loss_price, TSL_source - ATR_X2_TSL)
    TSL_transp := 0
plot(stop_loss_price, color=color.new(TSL_line_color, TSL_transp))
// }

// Variables for confirmations of entry {
_len_volat = input(20,title="Length of ATR to determine volatility")
_ATR_volat = atr(_len_volat)
_avg_atr = sma(_ATR_volat, _len_volat)
_std_volat = stdev(_ATR_volat,_len_volat)
signal_diverted_ATR = _ATR_volat > (_avg_atr + _std_volat) or _ATR_volat < (_avg_atr - _std_volat)

_len_drift = input(20,title="Length of Drift")//default set to const: _len_vol's default value
_prcntge_chng = log(close/close[1])
_drift = sma(_prcntge_chng, _len_drift) - pow(stdev(_prcntge_chng, _len_drift),2)*0.5
_chg_drift = _drift/_drift[1]-1
signal_uptrend = (_drift > _drift[1] and _drift > _drift[2]) or _drift > 0

entry_signal_all = signal_diverted_ATR and signal_uptrend
// }

alert_per_bar(msg)=>
    prefix = "[" + syminfo.root + "] "
    suffix = "(P=" + tostring(close) + "; atr=" + tostring(_ATR_volat) + ")"
    alert(tostring(prefix) + tostring(msg) + tostring(suffix), alert.freq_once_per_bar)

// MAIN {
if within_timeframe

    if strategy.position_size > 0 and strategy.position_size[1] > 0 and (stop_loss_price/stop_loss_price[1]-1) > 0.005
        alert_per_bar("TSL raised to " + tostring(stop_loss_price))

    // EXIT:
	if strategy.position_size > 0 and TSL_source <= stop_loss_price
	    exit_msg = close <= strategy.position_avg_price ? "stop loss" : "take profit"
        strategy.close(ENUM_LONG, comment=exit_msg)
    // ENTRY:
    else if entry_signal_all and (strategy.position_size == 0 or (strategy.position_size > 0 and close > stop_loss_price))
		entry_msg = strategy.position_size > 0 ? "adding" : "initial"
		strategy.entry(ENUM_LONG, strategy.long, comment=entry_msg)

if strategy.position_size == 0
    stop_loss_price := float(0)
// }


Thêm nữa