Chiến lược giao dịch định lượng SuperTrend cho Bitcoin

Tác giả:ChaoZhang, Ngày: 2024-02-06 12:09:09
Tags:

img

Tổng quan

Đây là một chiến lược giao dịch định lượng tự động cho Bitcoin dựa trên chỉ số SuperTrend. Nó sử dụng chỉ số SuperTrend để xác định xu hướng thị trường và kết hợp nguyên tắc dừng lỗ ATR để kiểm soát rủi ro, cho phép giao dịch dài và ngắn. Ưu điểm lớn nhất của chiến lược này là tỷ lệ rủi ro - phần thưởng tốt và chiến lược dừng lỗ đáng tin cậy, phù hợp với nắm giữ trung hạn đến dài hạn. Chiến lược này có thể được áp dụng trên các sàn giao dịch chính như Coinbase Pro sử dụng khung thời gian 4 giờ.

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

Chiến lược này sử dụng chỉ số SuperTrend để xác định hướng của xu hướng thị trường. Nó đi dài khi chỉ số SuperTrend thay đổi từ xu hướng giảm sang xu hướng tăng, và đi ngắn khi chỉ số SuperTrend thay đổi từ xu hướng tăng sang xu hướng giảm.

Cụ thể, chiến lược này đầu tiên tính toán khoảng thời gian ATR là 14 thanh, và xác định khoảng cách dừng lỗ cho mỗi giao dịch bằng cách nhân nó với nhân stop loss ATR (chẳng hạn như 1.5x). sau đó nó tính toán chỉ số SuperTrend bằng các tham số mặc định (thời gian ATR = 9, nhân SuperTrend = 2.5).

Sau khi tham gia giao dịch, mức dừng lỗ được cố định ở trên hoặc dưới mức dừng lỗ ATR. Mức độ lợi nhuận đầu tiên được tính dựa trên tỷ lệ rủi ro-lợi nhuận, mặc định là 0,75, có nghĩa là khoảng cách lấy lợi nhuận là 0,75 lần khoảng cách dừng lỗ. Khi giá đạt đến mức lợi nhuận đầu tiên, 50% vị trí sẽ được đóng, và stop loss được di chuyển đến mức giá nhập (break even) để khóa lợi nhuận. Mức độ lấy lợi nhuận thứ hai tiếp tục sử dụng tỷ lệ rủi ro-lợi nhuận 0,75. Nếu giá đạt mức dừng lỗ, vị trí còn lại sẽ được đóng bằng cách dừng lỗ.

Bằng cách đó, chiến lược này đảm bảo rủi ro dừng lỗ có thể kiểm soát được trong khi khóa lợi nhuận thông qua lợi nhuận lấy một phần, phù hợp với các chiến lược đầu tư trung và dài hạn.

Phân tích lợi thế

Ưu điểm lớn nhất của chiến lược này là tỷ lệ rủi ro-lợi nhuận tốt, cho phép nắm giữ trung bình đến dài hạn.

  1. Sử dụng SuperTrend để xác định xu hướng thị trường, lọc tiếng ồn thị trường và bắt các xu hướng chính.

  2. Theo dõi ATR năng động của dừng lỗ, kiểm soát đáng tin cậy lỗ giao dịch duy nhất.

  3. Mức lợi nhuận một phần bị khóa trong lợi nhuận, dẫn đến tỷ lệ rủi ro-lợi nhuận cao.

  4. Di chuyển dừng lỗ sang giá nhập cảnh sau khi đạt được TP1 khóa lợi nhuận và tăng tính ổn định chiến lược.

  5. Khá đơn giản logic, dễ hiểu và thực hiện, với không gian điều chỉnh tham số lớn.

  6. Áp dụng trên các sàn giao dịch chính sử dụng dữ liệu trong ngày hoặc tần số cao, linh hoạt cao.

Phân tích rủi ro

Chiến lược này cũng mang một số rủi ro, chủ yếu là trong các lĩnh vực sau:

  1. Có thể điều chỉnh ATR stop loss multiplier để giảm rủi ro.

  2. SuperTrend không thể xác định xu hướng đúng, dẫn đến tín hiệu giao dịch sai.

  3. Lấy tỷ lệ lợi nhuận quá cao, không thể đi theo xu hướng nên điều chỉnh dựa trên thị trường khác nhau.

  4. Tần suất giao dịch có thể quá cao hoặc quá thấp.

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

Vẫn còn nhiều chỗ để tối ưu hóa chiến lược này, chủ yếu trong các lĩnh vực sau:

  1. Kiểm tra các phương pháp dừng lỗ ATR khác nhau như ATR cố định, dừng động lực, dừng lỗ Bollinger vv.

  2. Tối ưu hóa các thông số SuperTrend bằng cách sử dụng các thuật toán tiến bộ hoặc di truyền để có các thông số tốt nhất.

  3. Thêm một lớp stop loss thứ hai như kênh Donchian để làm cho stop đáng tin cậy hơn.

  4. Kiểm tra các tỷ lệ lợi nhuận khác nhau để lấy lợi nhuận tối ưu so với cân bằng rủi ro.

  5. Khám phá các kỹ thuật học máy để dừng mất động, điều chỉnh vị trí vv

Kết luận

Đây là một chiến lược định lượng dựa trên SuperTrend cho xu hướng, ATR dừng động và lợi nhuận một phần. Nó có tỷ lệ rủi ro-lợi nhuận cân bằng, phù hợp với giao dịch algo. Có nhiều chỗ để tối ưu hóa các tham số, dừng lỗ, lấy lợi nhuận vv. Nó đáng điều chỉnh và áp dụng dài hạn.


/*backtest
start: 2024-01-06 00:00:00
end: 2024-02-05 00:00:00
period: 1h
basePeriod: 15m
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/
// Developed by © StrategiesForEveryone
//@version=5

strategy("SuperTrend Strategy for BTCUSD 4H", overlay=true, process_orders_on_close = true, initial_capital = 100, default_qty_type = strategy.cash, precision = 2, slippage = 50, commission_value = 0.03, backtest_fill_limits_assumption = 50)

// ------ Date filter (obtained from ZenAndTheArtOfTrading) ---------

initial_date = input(title="Initial date", defval=timestamp("10 Feb 2014 13:30 +0000"), group="Time filter", tooltip="Enter the start date and time of the strategy")
final_date   = input(title="Final date", defval=timestamp("01 Jan 2030 19:30 +0000"), group="Time filter", tooltip="Enter the end date and time of the strategy")
dateFilter(int st, int et) => time >= st and time <= et
colorDate = input.bool(defval=false, title="Date background", tooltip = "Add color to the period of time of the strategy tester")
bgcolor(colorDate and dateFilter(initial_date, final_date) ? color.new(color.blue, transp=90) : na)

// ------------ Super Trend ----------

atrPeriod = input(9, "ATR Length SuperTrend")
factor = input.float(2.5, "Factor SuperTrend", step = 0.05)
[supertrend, direction] = ta.supertrend(factor, atrPeriod)
show_supertrend = input.bool(defval = false, title="Show supertrend ?", group = "Appearance")
bodyMiddle = plot(show_supertrend ? ((open + close) / 2) : na, display=display.none)
upTrend = plot(show_supertrend and direction < 0 ? supertrend : na, "Up Trend", color = color.green, style=plot.style_linebr)
downTrend = plot(show_supertrend and direction > 0 ? supertrend : na, "Down Trend", color = color.red, style=plot.style_linebr)
fill(bodyMiddle, upTrend, color.new(color.green, 90), fillgaps=false)
fill(bodyMiddle, downTrend, color.new(color.red, 90), fillgaps=false)

// ---------- Atr stop loss (obtained from garethyeo)

source_atr = input(close, title='Source', group = "Atr stop loss", inline = "A")
length_atr = input.int(14, minval=1, title='Period', group = "Atr stop loss" , inline = "A")
multiplier = input.float(1.5, minval=0.1, step=0.1, title='Atr multiplier', group = "Atr stop loss", inline = "A", tooltip = "Defines the stop loss distance based on the Atr stop loss indicator")
shortStopLoss = source_atr + ta.atr(length_atr) * multiplier
longStopLoss = source_atr - ta.atr(length_atr) * multiplier
show_atr_stoploss = input.bool(defval=false, title="Show Atr stop loss ?", group = "Appearance")
plot(show_atr_stoploss ? longStopLoss : na, color=color.white, style = plot.style_circles)
plot(show_atr_stoploss ? shortStopLoss : na, color=color.white, style = plot.style_circles)

// ------------- Money management --------------

strategy_contracts = strategy.equity / close
distance_sl_atr_long = -1 * (longStopLoss - close) / close
distance_sl_atr_short = (shortStopLoss - close) / close
risk = input.float(2.5, '% Account risk per trade', step=1, group = "Risk management for trades", tooltip = "Percentage of total account to risk per trade")
long_amount = strategy_contracts * (risk / 100) / distance_sl_atr_long
short_amount = strategy_contracts * (risk / 100) / distance_sl_atr_short

// ---------- Risk management ---------------

risk_reward_breakeven_long= input.float(title="Risk/reward for breakeven long", defval=0.75, step=0.05, group = "Risk management for trades")
risk_reward_take_profit_long= input.float(title="Risk/reward for take profit long", defval=0.75, step=0.05, group = "Risk management for trades")
risk_reward_breakeven_short= input.float(title="Risk/reward for break even short", defval=0.75, step=0.05, group = "Risk management for trades")
risk_reward_take_profit_short= input.float(title="Risk/reward for take profit short", defval=0.75, step=0.05, group = "Risk management for trades")
tp_percent=input.float(title="% of trade for first take profit", defval=50, step=5, group = "Risk management for trades", tooltip = "Closing percentage of the current position when the first take profit is reached.")

// ------------ Trade conditions ---------------

bought = strategy.position_size > 0
sold = strategy.position_size < 0
long_supertrend=ta.crossover(close, supertrend)
short_supertrend=ta.crossunder(close, supertrend)
var float sl_long = na
var float sl_short = na 
var float be_long = na
var float be_short = na
var float tp_long = na
var float tp_short = na
if not bought
    sl_long:=na
if not sold
    sl_short:=na

// ---------- Strategy -----------

// Long position 

if not bought and long_supertrend
    sl_long:=longStopLoss           
    long_stoploss_distance = close - longStopLoss
    be_long := close + long_stoploss_distance * risk_reward_breakeven_long
    tp_long:=close+(long_stoploss_distance*risk_reward_take_profit_long)
    strategy.entry('L', strategy.long, long_amount, alert_message = "Long")
    strategy.exit("Tp", "L", stop=sl_long, limit=tp_long, qty_percent=tp_percent)
    strategy.exit('Exit', 'L', stop=sl_long)
if high > be_long
    sl_long := strategy.position_avg_price
    strategy.exit("Tp", "L", stop=sl_long, limit=tp_long, qty_percent=tp_percent)
    strategy.exit('Exit', 'L', stop=sl_long)
if bought and short_supertrend
    strategy.close("L", comment="CL")

// Short position

if not sold and short_supertrend
    sl_short:=shortStopLoss
    short_stoploss_distance=shortStopLoss - close  
    be_short:=((short_stoploss_distance*risk_reward_breakeven_short)-close)*-1
    tp_short:=((short_stoploss_distance*risk_reward_take_profit_short)-close)*-1
    strategy.entry("S", strategy.short, short_amount, alert_message = "Short")
    strategy.exit("Tp", "S", stop=sl_short, limit=tp_short, qty_percent=tp_percent)
    strategy.exit("Exit", "S", stop=sl_short)
if low < be_short
    sl_short:=strategy.position_avg_price
    strategy.exit("Tp", "S", stop=sl_short, limit=tp_short, qty_percent=tp_percent)
    strategy.exit("Exit", "S", stop=sl_short)    
if sold and long_supertrend
    strategy.close("S", comment="CS") 

// ---------- Draw position on chart -------------

if high>tp_long
    tp_long:=na
if low<tp_short
    tp_short:=na
if high>be_long
    be_long:=na
if low<be_short
    be_short:=na

show_position_on_chart = input.bool(defval=true, title="Draw position on chart ?", group = "Appearance", tooltip = "Activate to graphically display profit, stop loss and break even")
position_price = plot(show_position_on_chart? strategy.position_avg_price : na, style=plot.style_linebr, color = color.new(#ffffff, 10), linewidth = 1)

sl_long_price = plot(show_position_on_chart and bought ? sl_long : na, style = plot.style_linebr, color = color.new(color.red, 10), linewidth = 1)
sl_short_price = plot(show_position_on_chart and sold ? sl_short : na, style = plot.style_linebr, color = color.new(color.red, 10), linewidth = 1)

tp_long_price = plot(strategy.position_size>0 and show_position_on_chart? tp_long : na, style = plot.style_linebr, color = color.new(#11eb47, 10), linewidth = 1)
tp_short_price = plot(strategy.position_size<0 and show_position_on_chart? tp_short : na, style = plot.style_linebr, color = color.new(#11eb47, 10), linewidth = 1)

breakeven_long = plot(strategy.position_size>0 and high<be_long and show_position_on_chart ? be_long : na , style = plot.style_linebr, color = color.new(#00ff40, 60), linewidth = 1)
breakeven_short = plot(strategy.position_size<0 and low>be_short and show_position_on_chart ? be_short : na , style = plot.style_linebr, color = color.new(#00ff40, 60), linewidth = 1)

position_profit_long = plot(bought and show_position_on_chart and strategy.openprofit>0 ? close : na, style = plot.style_linebr, color = color.new(#4cd350, 10), linewidth = 1)
position_profit_short = plot(sold and show_position_on_chart and strategy.openprofit>0 ? close : na, style = plot.style_linebr, color = color.new(#4cd350, 10), linewidth = 1)

fill(plot1 = position_price, plot2 = position_profit_long, color = color.new(color.green,90))
fill(plot1 = position_price, plot2 = position_profit_short, color = color.new(color.green,90))

fill(plot1 = position_price, plot2 = sl_long_price, color = color.new(color.red,90))
fill(plot1 = position_price, plot2 = sl_short_price, color = color.new(color.red,90))

fill(plot1 = position_price, plot2 = tp_long_price, color = color.new(color.green,90))
fill(plot1 = position_price, plot2 = tp_short_price, color = color.new(color.green,90))


Thêm nữa