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

Chiến lược giao dịch đảo ngược đà phá vỡ động lực

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

img

Tổng quan

Chiến lược này sử dụng trung bình động đơn giản để xác định hướng xu hướng và đi dài trong xu hướng tăng và đi ngắn trong xu hướng giảm để thực hiện giao dịch đảo ngược.

Chiến lược logic

Chiến lược này sử dụng Trung bình Di chuyển Cân nhắc (VWMA) để xác định hướng xu hướng thị trường. Nó đi dài khi VWMA tăng và đi ngắn khi VWMA giảm.

Đặc biệt, nó đầu tiên tính toán VWMA của một khoảng thời gian nhất định, và sau đó đánh giá liệu VWMA đã tăng hơn 5 ngày. Nếu có, nó mở vị trí dài. Nếu VWMA đã giảm hơn 5 ngày, nó mở vị trí ngắn. Điều kiện đóng là khi hướng VWMA đảo ngược trong hơn 5 ngày.

Để tính toán lợi nhuận hàng tháng và hàng năm, chiến lược ghi lại lợi nhuận / lỗ của mỗi tháng và năm. Bằng cách so sánh lợi nhuận của chiến lược này với điểm chuẩn thị trường, chúng ta có thể nhìn thấy hiệu suất tương đối.

Phân tích lợi thế

Những lợi thế của chiến lược này bao gồm:

  1. Sử dụng VWMA để xác định xu hướng có thể lọc tiếng ồn thị trường hiệu quả và nắm bắt các xu hướng chính.

  2. Khởi mở vị trí chỉ sau khi xác nhận xu hướng có thể tránh rủi ro liên quan đến sự đảo ngược xu hướng.

  3. Giao dịch đảo ngược có thể kiếm lợi từ cả xu hướng tăng và giảm.

  4. Việc ghi lại lợi nhuận hàng tháng và hàng năm giúp đánh giá hiệu quả chiến lược dễ dàng hơn.

  5. Việc thêm các lợi nhuận so sánh thị trường cho phép so sánh trực tiếp giữa chiến lược và thị trường.

Phân tích rủi ro

Một số rủi ro của chiến lược này:

  1. Sử dụng VWMA để xác định xu hướng có thể chậm lại và bỏ lỡ cơ hội vào đầu xu hướng.

  2. Mở vị trí chỉ sau khi xác nhận có thể bỏ lỡ một số chuyển động.

  3. Giao dịch đảo ngược cần thiết lập dừng lỗ, nếu không lỗ có thể tăng lên.

  4. Sự biến động thị trường đáng kể có thể kích hoạt dừng lỗ và không thể giữ toàn bộ xu hướng.

  5. Phán quyết đảo ngược xu hướng có thể không chính xác, làm tăng tổn thất.

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

Một số khía cạnh có thể tối ưu hóa chiến lược:

  1. Tối ưu hóa tham số thời gian VWMA để cải thiện xác định xu hướng.

  2. Điều chỉnh số ngày để xác nhận xu hướng, cải thiện thời gian vào và ra.

  3. Thêm chiến lược dừng lỗ để kiểm soát lỗ giao dịch duy nhất.

  4. Bao gồm các chỉ số khác để xác định sự đảo ngược, cải thiện độ chắc chắn.

  5. Tối ưu hóa kích thước vị trí dựa trên điều kiện thị trường.

  6. Xem xét chi phí giao dịch, đặt mục tiêu lợi nhuận tối thiểu.

Tóm lại

Lý thuyết tổng thể của chiến lược này rất đơn giản và rõ ràng, sử dụng VWMA để xác định hướng xu hướng và giao dịch đảo ngược sau khi xác nhận, có thể theo dõi hiệu quả các chuyển động của thị trường. Nhưng nó cũng có một số rủi ro, đòi hỏi phải kiểm tra thêm và điều chỉnh tham số, điều chỉnh logic nhập / xuất, và kích thước vị trí thích hợp. Chiến lược giao dịch đảo ngược cơ bản này đặt nền tảng cho giao dịch định lượng và đáng nghiên cứu và cải thiện thêm.


/*backtest
start: 2023-01-01 00:00:00
end: 2023-10-26 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy(title="Monthly Returns in Strategies with Market Benchmark", shorttitle="Monthly P&L With Market", initial_capital= 1000, overlay=true,default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, commission_value = 0.1)
maLength= input(400)

wma= vwma(hl2,maLength)
uptrend= rising(wma, 5)
downtrend= falling(wma,5)

plot(wma)

if uptrend
    strategy.entry("Buy", strategy.long)
else
    strategy.close("Buy")//

///////////////////
// MONTHLY TABLE //

new_month = month(time) != month(time[1])
new_year  = year(time)  != year(time[1])

eq = strategy.equity

bar_pnl = eq / eq[1] - 1
bar_bh = (close-close[1])/close[1]

cur_month_pnl = 0.0
cur_year_pnl  = 0.0
cur_month_bh = 0.0
cur_year_bh  = 0.0

// Current Monthly P&L
cur_month_pnl := new_month ? 0.0 : 
                 (1 + cur_month_pnl[1]) * (1 + bar_pnl) - 1 
cur_month_bh := new_month ? 0.0 : 
                 (1 + cur_month_bh[1]) * (1 + bar_bh) - 1

// Current Yearly P&L
cur_year_pnl := new_year ? 0.0 : 
                 (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1
cur_year_bh := new_year ? 0.0 : 
                 (1 + cur_year_bh[1]) * (1 + bar_bh) - 1

// Arrays to store Yearly and Monthly P&Ls
var month_pnl  = array.new_float(0)
var month_time = array.new_int(0)
var month_bh  = array.new_float(0)

var year_pnl  = array.new_float(0)
var year_time = array.new_int(0)
var year_bh  = array.new_float(0)

last_computed = false

if (not na(cur_month_pnl[1]) and (new_month or time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory))
    if (last_computed[1])
        array.pop(month_pnl)
        array.pop(month_time)
        
    array.push(month_pnl , cur_month_pnl[1])
    array.push(month_time, time[1])
    array.push(month_bh , cur_month_bh[1])

if (not na(cur_year_pnl[1]) and (new_year or time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory))
    if (last_computed[1])
        array.pop(year_pnl)
        array.pop(year_time)
        
    array.push(year_pnl , cur_year_pnl[1])
    array.push(year_time, time[1])
    array.push(year_bh , cur_year_bh[1])

last_computed := (time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory) ? true : nz(last_computed[1])

// Monthly P&L Table    
var monthly_table = table(na)

getCellColor(pnl, bh)  => 
    if pnl > 0
        if bh < 0 or pnl > 2 * bh
            color.new(color.green, transp = 20)
        else if pnl > bh
            color.new(color.green, transp = 50)
        else
            color.new(color.green, transp = 80)
    else
        if bh > 0
            color.new(color.red, transp = 20)
        else if pnl < bh
            color.new(color.red, transp = 50)
        else
            color.new(color.red, transp = 80)

if last_computed
    monthly_table := table.new(position.bottom_right, columns = 14, rows = array.size(year_pnl) + 1, border_width = 1)

    table.cell(monthly_table, 0,  0, "",     bgcolor = #cccccc)
    table.cell(monthly_table, 1,  0, "Jan",  bgcolor = #cccccc)
    table.cell(monthly_table, 2,  0, "Feb",  bgcolor = #cccccc)
    table.cell(monthly_table, 3,  0, "Mar",  bgcolor = #cccccc)
    table.cell(monthly_table, 4,  0, "Apr",  bgcolor = #cccccc)
    table.cell(monthly_table, 5,  0, "May",  bgcolor = #cccccc)
    table.cell(monthly_table, 6,  0, "Jun",  bgcolor = #cccccc)
    table.cell(monthly_table, 7,  0, "Jul",  bgcolor = #cccccc)
    table.cell(monthly_table, 8,  0, "Aug",  bgcolor = #cccccc)
    table.cell(monthly_table, 9,  0, "Sep",  bgcolor = #cccccc)
    table.cell(monthly_table, 10, 0, "Oct",  bgcolor = #cccccc)
    table.cell(monthly_table, 11, 0, "Nov",  bgcolor = #cccccc)
    table.cell(monthly_table, 12, 0, "Dec",  bgcolor = #cccccc)
    table.cell(monthly_table, 13, 0, "Year", bgcolor = #999999)


    for yi = 0 to array.size(year_pnl) - 1
        table.cell(monthly_table, 0,  yi + 1, tostring(year(array.get(year_time, yi))), bgcolor = #cccccc)
        
        y_color = getCellColor(array.get(year_pnl, yi), array.get(year_bh, yi))
        table.cell(monthly_table, 13, yi + 1, tostring(round(array.get(year_pnl, yi) * 100)) + " (" + tostring(round(array.get(year_bh, yi) * 100)) + ")", bgcolor = y_color)
        
    for mi = 0 to array.size(month_time) - 1
        m_row   = year(array.get(month_time, mi))  - year(array.get(year_time, 0)) + 1
        m_col   = month(array.get(month_time, mi)) 
        m_color = getCellColor(array.get(month_pnl, mi), array.get(month_bh, mi))
        
        table.cell(monthly_table, m_col, m_row, tostring(round(array.get(month_pnl, mi) * 100)) + " (" + tostring(round(array.get(month_bh, mi) * 100)) +")", bgcolor = m_color)

Thêm nữa