Chiến lược đột phá gây sốc hai chiều


Ngày tạo: 2024-01-30 17:40:05 sửa đổi lần cuối: 2024-01-30 17:40:05
sao chép: 2 Số nhấp chuột: 589
1
tập trung vào
1617
Người theo dõi

Chiến lược đột phá gây sốc hai chiều

Tổng quan

Chiến lược này là một chiến lược giao dịch định lượng dựa trên sự phá vỡ của biến động giá hai chiều. Nó sử dụng điểm Pivot High/Low làm ngưỡng kháng cự quan trọng của giá, và làm nhiều khi giá phá vỡ điểm Pivot High, và làm trống khi phá vỡ điểm Pivot Low, để thực hiện hoạt động hai chiều.

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

Lập luận cốt lõi của chiến lược này dựa trên điểm đột phá quan trọng của giá cả hai chiều. Cụ thể, có một số bước sau:

  1. Tính toán Pivot High/Low của một chu kỳ nhất định. Các hàm ta.pivothigh () và ta.pivotlow () được sử dụng để tính toán giá cao nhất trong 2 ngày gần đây là giá cao và giá thấp nhất trong 1 ngày gần đây là giá thấp.

  2. Khi giá phá vỡ điểm cao quan trọng được tính toán ở trên, hãy mua thêm. Khi giá phá vỡ điểm thấp quan trọng, hãy tháo dỡ.

  3. Sử dụng đơn dừng lỗ dừng lỗ. Khi làm nhiều, giá dừng lỗ là điểm cao + đơn vị biến động giá tối thiểu; khi làm trống, giá dừng lỗ là điểm thấp - đơn vị biến động giá tối thiểu.

  4. Hình ảnh này có thể được sử dụng để vẽ các điểm cao và thấp của các điểm quan trọng để dễ dàng đánh giá trực quan.

Bằng cách này, khi có biến động giá, bạn có thể tham gia kịp thời khi phá vỡ các điểm quan trọng và dừng lại nhanh chóng, do đó có thể kiếm được lợi nhuận. Khi giá liên tục phá vỡ một mức cao mới hoặc thấp mới, chiến lược có thể tạo ra lợi nhuận tích lũy nhiều lần.

Phân tích lợi thế

Chiến lược đột phá hai chiều này có một số lợi thế:

  1. Đơn giản, dễ hiểu và dễ thực hiện. Chiến lược này rất đơn giản, chỉ cần vượt qua các điểm cao và thấp của Pivot để có thể tham gia.

  2. Dễ dàng thiết lập dừng lỗ. Làm nhiều giao dịch ngoại hối với điểm cao và điểm thấp + khoảng cách thay đổi nhỏ nhất làm điểm dừng lỗ, có thể dừng lỗ nhanh và kiểm soát rủi ro hiệu quả.

  3. Có thể hoạt động theo hai hướng. Bất kể thị trường có đi hay xuống, chiến lược này có thể được thực hiện theo chiều ngang và tích lũy lợi nhuận.

  4. Phương pháp này có thể được sử dụng để thu lợi nhuận khi giá tăng hoặc giảm thường xuyên.

Phân tích rủi ro

Mặc dù có những ưu điểm trên, chiến lược này cũng có một số rủi ro cần lưu ý:

  1. Việc xác định điểm quan trọng không đúng cách có thể làm tăng lỗ. Nếu thiết lập điểm quan trọng cao thấp không đúng cách, trong trường hợp cực đoan có thể theo đuổi cao hạ thấp.

  2. Chiến lược này có thể bắt đầu thua lỗ sau khi biến động kết thúc. Chiến lược này rất khó kiếm lợi nhuận khi giá bắt đầu có sự phá vỡ đơn phương thay vì biến động.

  3. Một đột phá có thể là một đột phá giả trong thời gian ngắn. Một đột phá giả có thể xảy ra trong thời gian ngắn, khiến chiến lược tạo ra giao dịch sai.

Nhìn chung, chiến lược này thích hợp hơn cho việc sử dụng trong tình huống chấn động. Các nhà đầu tư cần chú ý đến việc đánh giá tình huống và tránh sử dụng chiến lược này trong tình huống xu hướng.

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

Trong bối cảnh những rủi ro trên, chiến lược này có nhiều khả năng được tối ưu hóa như sau:

  1. Lựa chọn thông minh các tham số điểm cao và thấp quan trọng. Có thể sử dụng các phương tiện như học máy để hệ thống tự động tối ưu hóa lựa chọn các tham số điểm quan trọng phù hợp hơn.

  2. Kết hợp phán đoán xu hướng. Thêm logic phán đoán xu hướng trên cơ sở chiến lược, sử dụng chiến lược trong tình huống chấn động, đóng chiến lược trong xu hướng đơn phương, do đó giảm tổn thất.

  3. Tăng chiến lược dừng lỗ. Bạn có thể thiết kế các chiến lược dừng lỗ tinh tế hơn, chẳng hạn như dừng di chuyển, dừng phá vỡ khoảng, để kiểm soát rủi ro hơn nữa.

Tóm tắt

Chiến lược này là một chiến lược đột phá hai chiều đơn giản và thực tế. Nó dựa vào sự đột phá của điểm mấu chốt giá để vào thị trường và thiết lập rủi ro bảo đảm dừng lỗ có thể kiểm soát được. Chiến lược này phù hợp với tình trạng biến động, giao dịch hai chiều có thể kiếm được lợi nhuận.

Mã nguồn chiến lược
/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy('Monthly Returns with Benchmark', overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=25, commission_type=strategy.commission.percent, commission_value=0.1)

////////////
// Inputs //

// Pivot points inputs
leftBars   = input(2, group = "Pivot Points")
rightBars  = input(1, group = "Pivot Points")

// Styling inputs
prec       = input(2, title='Return Precision',                            group = "Monthly Table")
from_date  = input(timestamp("01 Jan 2000 00:00 +0000"), "From Date", group = "Monthly Table")
prof_color = input.color(color.green, title = "Gradient Colors", group = "Monthly Table", inline = "colors")
loss_color = input.color(color.red,   title = "",                group = "Monthly Table", inline = "colors")

// Benchmark inputs
use_cur    = input.bool(true,        title = "Use current Symbol for Benchmark", group = "Benchmark")
symb_bench = input('BTC_USDT:swap', title = "Benchmark",                        group = "Benchmark")
disp_bench = input.bool(true,        title = "Display Benchmark?",               group = "Benchmark")
disp_alpha = input.bool(true,        title = "Display Alpha?",                   group = "Benchmark")

// Pivot Points Strategy
swh = ta.pivothigh(leftBars, rightBars)
swl = ta.pivotlow(leftBars, rightBars)

hprice = 0.0
hprice := not na(swh) ? swh : hprice[1]

lprice = 0.0
lprice := not na(swl) ? swl : lprice[1]

le = false
le := not na(swh) ? true : le[1] and high > hprice ? false : le[1]

se = false
se := not na(swl) ? true : se[1] and low < lprice ? false : se[1]

if le
    strategy.entry('PivRevLE', strategy.long, comment='PivRevLE', stop=hprice + syminfo.mintick)

if se
    strategy.entry('PivRevSE', strategy.short, comment='PivRevSE', stop=lprice - syminfo.mintick)

plot(hprice, color=color.new(color.green, 0), linewidth=2)
plot(lprice, color=color.new(color.red, 0), linewidth=2)

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

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

eq       = strategy.equity
bench_eq = close

// benchmark eq
bench_eq_htf = request.security(symb_bench, timeframe.period, close)

if (not use_cur)
    bench_eq := bench_eq_htf

bar_pnl   = eq / eq[1] - 1
bench_pnl = bench_eq / bench_eq[1] - 1

cur_month_pnl = 0.0
cur_year_pnl  = 0.0

// Current Monthly P&L
cur_month_pnl := bar_index == 0 ? 0 : 
                 time >= from_date and (time[1] < from_date or new_month) ? bar_pnl : 
                 (1 + cur_month_pnl[1]) * (1 + bar_pnl) - 1

// Current Yearly P&L
cur_year_pnl  := bar_index == 0 ? 0 : 
                 time >= from_date and (time[1] < from_date or new_year) ? bar_pnl : 
                 (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1

bench_cur_month_pnl = 0.0
bench_cur_year_pnl  = 0.0

// Current Monthly P&L - Bench
bench_cur_month_pnl := bar_index == 0 or (time[1] < from_date and time >= from_date) ? 0 : 
                       time >= from_date and new_month ? bench_pnl : 
                       (1 + bench_cur_month_pnl[1]) * (1 + bench_pnl) - 1 

// Current Yearly P&L - Bench
bench_cur_year_pnl :=  bar_index == 0 ? 0 : 
                       time >= from_date and (time[1] < from_date  or new_year) ? bench_pnl : 
                       (1 + bench_cur_year_pnl[1]) * (1 + bench_pnl) - 1

var month_time = array.new_int(0)
var year_time  = array.new_int(0)

var month_pnl = array.new_float(0)
var year_pnl  = array.new_float(0)

var bench_month_pnl = array.new_float(0)
var bench_year_pnl  = array.new_float(0)

// Filling monthly / yearly pnl arrays
if array.size(month_time) > 0
    if month(time) == month(array.get(month_time, array.size(month_time) - 1))
        array.pop(month_pnl)
        array.pop(bench_month_pnl)
        array.pop(month_time)

if array.size(year_time) > 0
    if year(time) == year(array.get(year_time, array.size(year_time) - 1))
        array.pop(year_pnl)
        array.pop(bench_year_pnl)
        array.pop(year_time)

if (time >= from_date)
    array.push(month_time, time)
    array.push(year_time,  time)
    
    array.push(month_pnl, cur_month_pnl)
    array.push(year_pnl,  cur_year_pnl)
    
    array.push(bench_year_pnl,  bench_cur_year_pnl)
    array.push(bench_month_pnl, bench_cur_month_pnl)

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

if array.size(year_pnl) > 0 and barstate.islastconfirmedhistory

    monthly_table := table.new(position.bottom_right, columns=15, rows=array.size(year_pnl) * 3 + 5, border_width=1)

    // Fill monthly performance

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

    max_abs_y = math.max(math.abs(array.max(year_pnl)),  math.abs(array.min(year_pnl)))
    max_abs_m = math.max(math.abs(array.max(month_pnl)), math.abs(array.min(month_pnl)))

    for yi = 0 to array.size(year_pnl) - 1 by 1
        table.cell(monthly_table, 0,  yi + 1, str.tostring(year(array.get(year_time, yi))), bgcolor=#cccccc)
        table.cell(monthly_table, 13, yi + 1, ' ',   bgcolor=#999999)
        y_color = color.from_gradient(array.get(year_pnl, yi), -max_abs_y, max_abs_y, loss_color, prof_color) 
        table.cell(monthly_table, 14, yi + 1, str.tostring(math.round(array.get(year_pnl, yi) * 100, prec)), bgcolor=y_color)

    for mi = 0 to array.size(month_time) - 1 by 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 = color.from_gradient(array.get(month_pnl, mi), -max_abs_m, max_abs_m, loss_color, prof_color)

        table.cell(monthly_table, m_col, m_row, str.tostring(math.round(array.get(month_pnl, mi) * 100, prec)), bgcolor=m_color)
    
    // Fill benchmark performance
    next_row =  array.size(year_pnl) + 1  
    
    if (disp_bench)
    
        table.cell(monthly_table, 0,  next_row, 'Bench', bgcolor=#999999)
        table.cell(monthly_table, 1,  next_row, 'Jan',   bgcolor=#999999)
        table.cell(monthly_table, 2,  next_row, 'Feb',   bgcolor=#999999)
        table.cell(monthly_table, 3,  next_row, 'Mar',   bgcolor=#999999)
        table.cell(monthly_table, 4,  next_row, 'Apr',   bgcolor=#999999)
        table.cell(monthly_table, 5,  next_row, 'May',   bgcolor=#999999)
        table.cell(monthly_table, 6,  next_row, 'Jun',   bgcolor=#999999)
        table.cell(monthly_table, 7,  next_row, 'Jul',   bgcolor=#999999)
        table.cell(monthly_table, 8,  next_row, 'Aug',   bgcolor=#999999)
        table.cell(monthly_table, 9,  next_row, 'Sep',   bgcolor=#999999)
        table.cell(monthly_table, 10, next_row, 'Oct',   bgcolor=#999999)
        table.cell(monthly_table, 11, next_row, 'Nov',   bgcolor=#999999)
        table.cell(monthly_table, 12, next_row, 'Dec',   bgcolor=#999999)
        table.cell(monthly_table, 13, next_row, ' ',     bgcolor = #999999)
        table.cell(monthly_table, 14, next_row, 'Year',  bgcolor=#999999)
    
        max_bench_abs_y = math.max(math.abs(array.max(bench_year_pnl)),  math.abs(array.min(bench_year_pnl)))
        max_bench_abs_m = math.max(math.abs(array.max(bench_month_pnl)), math.abs(array.min(bench_month_pnl)))
    
        for yi = 0 to array.size(year_time) - 1 by 1
            table.cell(monthly_table, 0,  yi + 1 + next_row + 1, str.tostring(year(array.get(year_time, yi))), bgcolor=#cccccc)
            table.cell(monthly_table, 13, yi + 1 + next_row + 1, ' ',   bgcolor=#999999)
            y_color = color.from_gradient(array.get(bench_year_pnl, yi), -max_bench_abs_y, max_bench_abs_y, loss_color, prof_color)
            table.cell(monthly_table, 14, yi + 1 + next_row + 1, str.tostring(math.round(array.get(bench_year_pnl, yi) * 100, prec)), bgcolor=y_color)
     
        for mi = 0 to array.size(month_time) - 1 by 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 = color.from_gradient(array.get(bench_month_pnl, mi), -max_bench_abs_m, max_bench_abs_m, loss_color, prof_color)
    
            table.cell(monthly_table, m_col, m_row  + next_row + 1, str.tostring(math.round(array.get(bench_month_pnl, mi) * 100, prec)), bgcolor=m_color)
    
    // Fill Alpha
    if (disp_alpha)
    
        next_row :=  array.size(year_pnl) * 2 + 3   
        table.cell(monthly_table, 0,  next_row, 'Alpha', bgcolor=#999999)
        table.cell(monthly_table, 1,  next_row, 'Jan',   bgcolor=#999999)
        table.cell(monthly_table, 2,  next_row, 'Feb',   bgcolor=#999999)
        table.cell(monthly_table, 3,  next_row, 'Mar',   bgcolor=#999999)
        table.cell(monthly_table, 4,  next_row, 'Apr',   bgcolor=#999999)
        table.cell(monthly_table, 5,  next_row, 'May',   bgcolor=#999999)
        table.cell(monthly_table, 6,  next_row, 'Jun',   bgcolor=#999999)
        table.cell(monthly_table, 7,  next_row, 'Jul',   bgcolor=#999999)
        table.cell(monthly_table, 8,  next_row, 'Aug',   bgcolor=#999999)
        table.cell(monthly_table, 9,  next_row, 'Sep',   bgcolor=#999999)
        table.cell(monthly_table, 10, next_row, 'Oct',   bgcolor=#999999)
        table.cell(monthly_table, 11, next_row, 'Nov',   bgcolor=#999999)
        table.cell(monthly_table, 12, next_row, 'Dec',   bgcolor=#999999)
        table.cell(monthly_table, 13, next_row, '',      bgcolor=#999999)
        table.cell(monthly_table, 14, next_row, 'Year',  bgcolor=#999999)
        
        max_alpha_abs_y = 0.0
        for yi = 0 to array.size(year_time) - 1 by 1
            if (math.abs(array.get(year_pnl, yi)  - array.get(bench_year_pnl, yi)) > max_alpha_abs_y)
                max_alpha_abs_y := math.abs(array.get(year_pnl, yi)  - array.get(bench_year_pnl, yi))
    
        max_alpha_abs_m = 0.0
        for mi = 0 to array.size(month_pnl) - 1 by 1
            if (math.abs(array.get(month_pnl, mi) - array.get(bench_month_pnl, mi)) > max_alpha_abs_m)
                max_alpha_abs_m := math.abs(array.get(month_pnl, mi) - array.get(bench_month_pnl, mi))
                
        for yi = 0 to array.size(year_time) - 1 by 1
            table.cell(monthly_table, 0,  yi + 1 + next_row + 1, str.tostring(year(array.get(year_time, yi))), bgcolor=#cccccc)
            table.cell(monthly_table, 13, yi + 1 + next_row + 1, ' ',   bgcolor=#999999)
            y_color = color.from_gradient(array.get(year_pnl, yi)  - array.get(bench_year_pnl, yi), -max_alpha_abs_y, max_alpha_abs_y, loss_color, prof_color)
            table.cell(monthly_table, 14, yi + 1 + next_row + 1, str.tostring(math.round((array.get(year_pnl, yi)  - array.get(bench_year_pnl, yi)) * 100, prec)), bgcolor=y_color)
     
        for mi = 0 to array.size(month_time) - 1 by 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 = color.from_gradient(array.get(month_pnl, mi) - array.get(bench_month_pnl, mi), -max_alpha_abs_m, max_alpha_abs_m, loss_color, prof_color)
    
            table.cell(monthly_table, m_col, m_row  + next_row + 1, str.tostring(math.round((array.get(month_pnl, mi) - array.get(bench_month_pnl, mi)) * 100, prec)), bgcolor=m_color)