Tỷ lệ thay đổi Chiến lược định lượng

Tác giả:ChaoZhang, Ngày: 2023-12-12 15:56:56
Tags:

img

Tổng quan

Chiến lược này sử dụng chỉ số Rate of Change (ROC) để xác định hướng thị trường và tạo ra các tín hiệu giao dịch. Ý tưởng cốt lõi của chiến lược là theo dõi xu hướng dài hạn và vượt trội hơn thị trường bằng cách chấp nhận rủi ro lớn hơn.

Chiến lược logic

Quy tắc nhập cảnh

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

Dừng Loss

Khi stop loss được kích hoạt, đảo ngược vị trí. điều này cho thấy chúng ta có thể đang ở bên trái của thị trường vì vậy chúng ta thoát ngay lập tức.

Cơ chế chống bong bóng

Nếu ROC vượt quá 200, thị trường được coi là bong bóng. Khi ROC giảm xuống dưới vùng bong bóng, tín hiệu đi ngắn được kích hoạt. Yêu cầu bong bóng tồn tại ít nhất 1 tuần.

Quản lý tiền bạc

Sử dụng phương pháp định kích thước vị trí cố định + gia tăng. Tăng / giảm vị trí 200 đô la cho mỗi 400 đô la lợi nhuận / lỗ. Điều này cho phép chúng ta kiếm được lợi nhuận kim tự tháp nhưng cũng làm tăng rút tiền.

Phân tích lợi thế

Ưu điểm của chiến lược này:

  1. Phù hợp với xu hướng theo triết lý có khả năng tạo ra lợi nhuận tích cực lâu dài.
  2. Sử dụng stop loss để kiểm soát rủi ro và giảm biến động ngắn hạn.
  3. Cơ chế chống bong bóng tránh đuổi theo đỉnh.
  4. Vị trí cố định + phương pháp gia tăng tạo ra sự tăng trưởng theo cấp số nhân trong xu hướng tăng.

Phân tích rủi ro

Một số rủi ro cũng tồn tại:

  1. Chỉ số ROC dễ bị chọc chích tạo ra tín hiệu sai.
  2. Chi phí giao dịch không được xem xét làm giảm lợi nhuận thực tế.
  3. Điều chỉnh tham số chống bong bóng kém cũng bỏ lỡ xu hướng.
  4. Kích thước tăng dần làm tăng lượng thu hồi khi thua.

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

Một số cách để tối ưu hóa chiến lược:

  1. Thêm các chỉ số khác vào các tín hiệu lọc, chẳng hạn như MA, Volatility v.v.
  2. Tối ưu hóa các thông số chống bong bóng để phát hiện bong bóng tốt hơn.
  3. Điều chỉnh vị trí cố định và tỷ lệ gia tăng để cân bằng rủi ro / lợi nhuận tốt hơn.
  4. Thêm stop loss tự động khi xảy ra lỗ lớn.
  5. Xem xét chi phí giao dịch và thiết lập các quy tắc nhập cảnh phù hợp.

Kết luận

Tóm lại, đây là một xu hướng dài hạn sau chiến lược tập trung vào chỉ số ROC. Nó nhằm mục đích tạo ra alpha bằng cách chấp nhận rủi ro cao hơn.


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


Thêm nữa