Chiến lược giao dịch tiền điện tử tăng/ giảm dựa trên mối tương quan dựa trên chỉ số CCI của Phố Wall

Tác giả:ChaoZhang, Ngày: 2023-11-01 11:27:20
Tags:

img

Tổng quan

Đây là một chiến lược giao dịch tự động tạo ra các tín hiệu dài / ngắn / gần trên tiền điện tử mục tiêu dựa trên xu hướng tính toán của một tiền điện tử tiêu chuẩn được coi là tương quan với nó, sử dụng Chỉ số Vòng đuổi Phố Wall.

Với các thông số mặc định và ETH / USDT là biểu tượng cơ bản, chiến lược cho thấy kết quả backtest tốt trên các biểu tượng như DENT / USDT, BTT / USDT, FTT / USDT, DOT / USDT vv. Điều này có ý nghĩa vì ETH khá có ảnh hưởng trong thị trường tiền điện tử vì vậy nhiều tiền điện tử có xu hướng theo các chuyển động lớn của ETH.

Lưu ý: Chiến lược với các tham số mặc định được thiết kế cho khung thời gian 4h. Trên các khung thời gian khác, hãy thử chiều dài hỗ trợ khác.

Chiến lược hoạt động như thế nào

  1. Một WMA được tính trên biểu tượng cơ sở, với chiều dài 200 theo mặc định.

  2. Khi WMA đang tăng, hãy đi dài. Khi giảm đi ngắn.

  3. TakeProfit cho Long/Short và StopLoss cho Long/Short là tỷ lệ phần trăm được tính toán vì vậy 0,05 = 5% v.v. Ngoài ra, TakeProfit / StopLoss được tính trên biểu tượng cơ sở chứ không phải biểu tượng biểu đồ.

  4. Chiến lược sử dụng lệnh thị trường để vào và ra dựa trên logic sau:

    • Khi WMA tăng và không có vị trí, đầu vào dài

    • Khi WMA giảm và không có vị trí, nhập ngắn

    • Khi lợi nhuận vị trí dài >= TakeProfitLong phần trăm, đóng dài

    • Khi lợi nhuận vị trí ngắn >= TakeProfitShort phần trăm, đóng ngắn

    • Khi lỗ vị trí dài >= StopLossLong phần trăm, đóng dài

    • Khi lỗ vị trí ngắn >= StopLossShort phần trăm, đóng ngắn

  5. Giá TakeProfit và StopLoss được cập nhật trong thời gian thực dựa trên sự thay đổi giá biểu tượng cơ sở.

Phân tích lợi thế

  1. Chiến lược có khả năng thích nghi cao để sử dụng trên nhiều loại tiền điện tử bằng cách điều chỉnh các tham số.

  2. Sử dụng CCI của Phố Wall để xác định xu hướng tránh các giao dịch sai do tiếng ồn.

  3. Kết hợp TakeProfit và StopLoss cho phép theo xu hướng trong khi kiểm soát lỗ cho mỗi giao dịch.

  4. Giao dịch tự động hoàn toàn mà không cần can thiệp bằng tay cho phép hoạt động 24/7.

Phân tích rủi ro

  1. Nguy cơ giá tiền điện tử mục tiêu tách khỏi tiền điện tử cơ sở, dẫn đến thất bại của chiến lược. Có thể tối ưu hóa bằng cách sử dụng nhiều tiền điện tử cơ sở và chọn tiền điện tử có tương quan cao nhất.

  2. Có thể điều chỉnh StopLoss phần trăm hoặc sử dụng trailing stop.

  3. Rủi ro của TakeProfit phần trăm quá nhỏ để nắm bắt đủ lợi nhuận xu hướng. Có thể kết hợp theo dõi xu hướng hoặc lợi nhuận động.

  4. Có thể điều chỉnh các tham số CCI hoặc thêm logic nhập lại.

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

  1. Sử dụng phân tích tương quan giữa nhiều mã hóa cơ sở và kết hợp các chỉ số để giảm rủi ro mã hóa cơ sở duy nhất.

  2. Thêm theo dõi xu hướng để điều chỉnh động TakeProfit / StopLoss dựa trên biến động.

  3. Thêm các bước dừng để ngăn chặn các động thái cực đoan dừng lại các vị trí.

  4. Thêm logic nhập lại để tránh bỏ lỡ xu hướng tiếp theo sau khi thoát khỏi lỗ dừng.

  5. Tối ưu hóa các thông số và cài đặt CCI để cải thiện hiệu quả tín hiệu.

  6. Tối ưu hóa các tham số riêng biệt cho mỗi crypto mục tiêu để cải thiện khả năng thích nghi.

  7. Tối ưu hóa kích thước vị trí dựa trên kích thước tài khoản.

Tóm lại

Nói chung, đây là một chiến lược theo xu hướng điển hình. Ý tưởng cốt lõi là xác định hướng xu hướng của một tiền điện tử chuẩn bằng cách sử dụng CCI của Phố Wall và giao dịch tiền điện tử mục tiêu theo đó. Chiến lược có một số lợi thế nhưng cũng có những rủi ro cần lưu ý.


/*backtest
start: 2022-10-25 00:00:00
end: 2023-10-31 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/
// © levieux

//@version=5
strategy(title='Correlation Strategy', shorttitle='Correlation Strategy', 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)

supportLength = input.int(200, minval=1, title='Support Length')
supportSymbol = input('BTC_USDT:swap', title='Correlated Symbol')
supportSource = input(hlc3, title='Price Source')
takeprofitLong = input.float(0.2, 'Take Profit Long', step=0.01)
takeprofitShort = input.float(0.15, 'Take Profit Short', step=0.01)
stoplossLong = input.float(0.1, 'Stop Loss Long', step=0.01)
stoplossShort = input.float(0.04, 'Stop Loss Short', step=0.01)
start = input(defval = timestamp("01 Jan 2016 00:00 +0000"), title = "Start Time")
end = input(defval = timestamp("31 Dec 2050 23:59 +0000"), title = "End Time")

supportTicker = request.security(supportSymbol, timeframe.period, supportSource, lookahead=barmerge.lookahead_off)  //input(close, title="Source")
supportLine = ta.wma(supportTicker, supportLength)

window() => true

if not window()
    strategy.cancel_all()

supportLongPrice = close
supportShortPrice = close

if strategy.position_size > 0
    supportLongPrice := supportLongPrice[1]
if strategy.position_size < 0
    supportShortPrice := supportShortPrice[1]

longCondition = ta.rising(supportLine, 5) and window() and strategy.position_size <= 0
shortCondition = ta.falling(supportLine, 5) and window() and window() and strategy.position_size > 0
takeprofitLongCondition = takeprofitLong > 0 and window() and strategy.position_size > 0 and supportTicker > supportLongPrice * (1 + takeprofitLong)
stoplossLongCondition = stoplossLong > 0 and window() and strategy.position_size > 0 and supportTicker < supportLongPrice * (1 - stoplossLong)
takeprofitShortCondition = takeprofitShort > 0 and window() and strategy.position_size < 0 and supportTicker > supportShortPrice * (1 + takeprofitShort)
stoplossShortCondition = stoplossShort > 0 and window() and strategy.position_size < 0 and supportTicker < supportShortPrice * (1 - stoplossShort)

if longCondition
    strategy.entry('Long', strategy.long)
    supportLongPrice := supportTicker

if shortCondition
    strategy.entry('Short', strategy.short)
    supportShortPrice := supportTicker

if takeprofitLongCondition
    strategy.close('Long')
if stoplossLongCondition
    strategy.close('Long')
if takeprofitShortCondition
    strategy.close('Short')
if stoplossShortCondition
    strategy.close('Short')

///////////////////
// 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)

end_time = false

end_time:= time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory

if (not na(cur_month_pnl[1]) and (new_month or end_time))
    if (end_time[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 end_time))
    if (end_time[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])

// 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 or pnl < 2 * bh
            color.new(color.red, transp = 20)
        else if pnl < bh
            color.new(color.red, transp = 50)
        else
            color.new(color.red, transp = 80)

if end_time
    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, str.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, str.tostring(math.round(array.get(year_pnl, yi) * 100)) + " (" + str.tostring(math.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, str.tostring(math.round(array.get(month_pnl, mi) * 100)) + " (" + str.tostring(math.round(array.get(month_bh, mi) * 100)) +")", bgcolor = m_color)

Thêm nữa