Chiến lược định lượng dựa trên tỷ lệ thay đổi


Ngày tạo: 2023-12-12 15:56:56 sửa đổi lần cuối: 2023-12-12 15:56:56
sao chép: 0 Số nhấp chuột: 655
1
tập trung vào
1621
Người theo dõi

Chiến lược định lượng dựa trên tỷ lệ thay đổi

Tổng quan

Chiến lược này dựa trên tỷ lệ thay đổi (ROC) để đánh giá xu hướng thị trường và tạo ra tín hiệu giao dịch. Ý tưởng cốt lõi của chiến lược là theo xu hướng dài hạn, nhận được lợi nhuận vượt quá thị trường bằng cách chịu rủi ro lớn hơn.

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

Quy tắc nhập cảnh

  • Nếu ROC> 0, làm nhiều; nếu ROC< 0, làm trống. Sử dụng chỉ số ROC tích cực để đánh giá hướng đi của thị trường.
  • Để lọc choáng, chỉ khi ROC ở cùng một bên trong hai ngày liên tiếp, tín hiệu giao dịch sẽ được phát ra.

Quy tắc dừng lỗ

Cài đặt Stop loss là 6%. Khi Stop loss được kích hoạt, thay đổi hướng vị trí. Điều này có nghĩa là chúng ta có thể đang ở bên trái của thị trường và cần phải thực hiện Stop Loss Reversal kịp thời.

Cơ chế chống bong bóng

Nếu ROC vượt quá 200, nó được coi là một bong bóng. Khi ROC rơi xuống dưới bong bóng, nó tạo ra tín hiệu trống. Đồng thời, yêu cầu bong bóng kéo dài ít nhất 1 tuần.

Quản lý tài chính

Sử dụng phương pháp cố định + gia tăng. Mỗi lần tăng hoặc giảm 400 đô la, tăng hoặc giảm 200 đô la. Như vậy, bạn có thể sử dụng lợi nhuận để gia tăng để có được lợi nhuận lớn hơn, nhưng cũng tăng rút lui.

Phân tích lợi thế

Đây là một chiến lược để theo dõi xu hướng dài hạn.

  1. Theo triết lý giao dịch theo xu hướng, bạn có thể dễ dàng thu được lợi nhuận tích cực lâu dài.
  2. Sử dụng lệnh dừng để kiểm soát rủi ro có thể làm giảm tác động của biến động thị trường ngắn hạn.
  3. Các cơ chế chống bong bóng có thể tránh được sự tăng giá ở đỉnh thị trường.
  4. Vị trí cố định + quản lý vốn gia tăng cho phép nó tăng trưởng theo chỉ số trong bối cảnh tăng trưởng.

Phân tích rủi ro

Chiến lược này cũng có một số rủi ro:

  1. Chỉ số ROC dễ bị ảnh hưởng bởi sóng động, tạo ra tín hiệu sai. Bạn có thể xem xét thêm các chỉ số khác để lọc kết hợp.
  2. Không tính chi phí giao dịch, lợi nhuận khi sử dụng thực tế sẽ thấp hơn so với đánh giá.
  3. Các tham số chống bong bóng được đặt không đúng cách cũng dễ bị bỏ lỡ.
  4. Vị trí cố định + tăng trưởng làm tăng sự rút lui khi mất mát.

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

Chiến lược này có thể được tối ưu hóa theo các khía cạnh sau:

  1. Thêm các chỉ số khác để đánh giá, tạo thành hệ thống giao dịch để lọc các tín hiệu sai. Ví dụ như thêm các chỉ số như đường trung bình, tỷ lệ biến động.
  2. Tối ưu hóa các tham số chống bọt, thiết lập cơ chế nhận diện bọt chính xác hơn.
  3. Điều chỉnh vị trí cố định và tham số gia tăng để có được sự cân bằng lợi nhuận rủi ro tốt hơn.
  4. Thêm cơ chế tự động dừng lỗ.
  5. Cân nhắc đến tác động của phí giao dịch, thiết lập các tiêu chuẩn nhập cảnh thực tế hơn.

Tóm tắt

Nhìn chung, đây là một chiến lược theo dõi đường dài với chỉ số ROC là cốt lõi. Nó là một chiến lược tích cực để có được lợi nhuận vượt quá cổ phiếu lớn bằng cách chấp nhận rủi ro lớn hơn. Chúng ta cần tối ưu hóa đúng cách để có thể sử dụng trong thực tế.

Mã nguồn chiến lược
/*backtest
start: 2022-12-05 00:00:00
end: 2023-12-11 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/
// © gsanson66


//This strategy use the Rate of Change (ROC) of the closing price to send enter signal. 
//@version=5
strategy("RATE OF CHANGE BACKTESTING", shorttitle="ROC BACKTESTING", overlay=false, precision=3, initial_capital=1000, default_qty_type=strategy.cash, default_qty_value=950, commission_type=strategy.commission.percent, commission_value=0.18)


//--------------------------------FUNCTIONS-----------------------------------//

//@function Displays text passed to `txt` when called.
debugLabel(txt, color, loc) =>
    label.new(bar_index, loc, text = txt, color=color, style = label.style_label_lower_right, textcolor = color.black, size = size.small)

//@function which looks if the close date of the current bar falls inside the date range
inBacktestPeriod(start, end) => (time >= start) and (time <= end)


//----------------------------------USER INPUTS----------------------------------//

//Technical parameters
rocLength = input.int(defval=365, minval=0, title='ROC Length', group="Technical parameters")
bubbleValue = input.int(defval=200, minval=0, title="ROC Bubble signal", group="Technical parameters")
//Risk management
stopLossInput = input.float(defval=10, minval=0, title="Stop Loss (in %)", group="Risk Management")
//Money management
fixedRatio = input.int(defval=400, minval=1, title="Fixed Ratio Value ($)", group="Money Management")
increasingOrderAmount = input.int(defval=200, minval=1, title="Increasing Order Amount ($)", group="Money Management")
//Backtesting period
startDate = input(title="Start Date", defval=timestamp("1 Jan 2017 00:00:00"), group="Backtesting Period")
endDate = input(title="End Date", defval=timestamp("1 July 2024 00:00:00"), group="Backtesting Period")


//-------------------------------------VARIABLES INITIALISATION-----------------------------//

roc = (close/close[rocLength] - 1)*100
midlineConst = 0
var bool inBubble = na
bool shortBubbleCondition = na
equity = strategy.equity - strategy.openprofit
strategy.initial_capital = 50000
var float capital_ref = strategy.initial_capital
var float cashOrder = strategy.initial_capital * 0.95
bool inRange = na


//------------------------------CHECKING SOME CONDITIONS ON EACH SCRIPT EXECUTION-------------------------------//

//Checking if the date belong to the range
inRange := true

//Checking if we are in a bubble
if roc > bubbleValue and not inBubble
    inBubble := true

//Checking if the bubble is over
if roc < 0 and inBubble
    inBubble := false

//Checking the condition to short the bubble : The ROC must be above the bubblevalue for at least 1 week
if roc[1]>bubbleValue and roc[2]>bubbleValue and roc[3]>bubbleValue and roc[4]>bubbleValue and roc[5]>bubbleValue and roc[6]>bubbleValue and roc[7]>bubbleValue
    shortBubbleCondition := true

//Checking performances of the strategy
if equity > capital_ref + fixedRatio
    spread = (equity - capital_ref)/fixedRatio
    nb_level = int(spread)
    increasingOrder = nb_level * increasingOrderAmount
    cashOrder := cashOrder + increasingOrder
    capital_ref := capital_ref + nb_level*fixedRatio
if equity < capital_ref - fixedRatio
    spread = (capital_ref - equity)/fixedRatio
    nb_level = int(spread)
    decreasingOrder = nb_level * increasingOrderAmount
    cashOrder := cashOrder - decreasingOrder
    capital_ref := capital_ref - nb_level*fixedRatio

//Checking if we close all trades in case where we exit the backtesting period
if strategy.position_size!=0 and not inRange
    debugLabel("END OF BACKTESTING PERIOD : we close the trade", color=color.rgb(116, 116, 116), loc=roc)
    strategy.close_all()


//-------------------------------LONG/SHORT CONDITION-------------------------------//

//Long condition
//We reduce noise by taking signal only if the last roc value is in the same side as the current one
if (strategy.position_size<=0 and ta.crossover(roc, midlineConst)[1] and roc>0 and inRange)
    //If we were in a short position, we pass to a long position
    qty = cashOrder/close
    strategy.entry("Long", strategy.long, qty)
    stopLoss = close * (1-stopLossInput/100)
    strategy.exit("Long Risk Managment", "Long", stop=stopLoss)

//Short condition
//We take a short position if we are in a bubble and roc is decreasing
if (strategy.position_size>=0 and ta.crossunder(roc, midlineConst)[1] and roc<0 and inRange) or 
     (strategy.position_size>=0 and inBubble and ta.crossunder(roc, bubbleValue) and shortBubbleCondition and inRange)
    //If we were in a long position, we pass to a short position
    qty = cashOrder/close
    strategy.entry("Short", strategy.short, qty)
    stopLoss = close * (1+stopLossInput/100)
    strategy.exit("Short Risk Managment", "Short", stop=stopLoss)


//--------------------------------RISK MANAGEMENT--------------------------------------//

//We manage our risk and change the sense of position after SL is hitten
if strategy.position_size == 0 and inRange
    //We find the direction of the last trade
    id = strategy.closedtrades.entry_id(strategy.closedtrades-1)
    if id == "Short"
        qty = cashOrder/close
        strategy.entry("Long", strategy.long, qty)
        stopLoss = close * (1-stopLossInput/100)
        strategy.exit("Long Risk Managment", "Long", stop=stopLoss)
    else if id =="Long"
        qty = cashOrder/close
        strategy.entry("Short", strategy.short, qty)
        stopLoss = close * (1+stopLossInput/100)
        strategy.exit("Short Risk Managment", "Short", stop=stopLoss)


//---------------------------------PLOTTING ELEMENTS---------------------------------------//

//Plotting of ROC
rocPlot = plot(roc, "ROC", color=#7E57C2)
midline = hline(0, "ROC Middle Band", color=color.new(#787B86, 25))
midLinePlot = plot(0, color = na, editable = false, display = display.none)
fill(rocPlot, midLinePlot, 40, 0, top_color = strategy.position_size>0 ? color.new(color.green, 0) : strategy.position_size<0 ? color.new(color.red, 0) : na, bottom_color = strategy.position_size>0 ? color.new(color.green, 100) : strategy.position_size<0 ? color.new(color.red, 100) : na,  title = "Positive area")
fill(rocPlot, midLinePlot, 0,  -40,  top_color = strategy.position_size<0 ? color.new(color.red, 100) : strategy.position_size>0 ? color.new(color.green, 100) : na, bottom_color = strategy.position_size<0 ? color.new(color.red, 0) : strategy.position_size>0 ? color.new(color.green, 0) : na, title = "Negative area")