Chiến lược đảo ngược phạm vi ngủ

Tác giả:ChaoZhang, Ngày: 2023-10-30 10:54:00
Tags:

img

Tổng quan

Chiến lược đảo ngược dải ngủ sử dụng các giai đoạn biến động giảm như tín hiệu đầu vào và nhằm mục đích kiếm lợi nhuận khi biến động tăng trở lại. Nó xác định các tình huống mà giá được chứa trong một dải ngủ hẹp và nắm bắt xu hướng giá sắp tới. Chiến lược này hoạt động tốt khi biến động hiện tại thấp nhưng dự kiến sẽ phá vỡ.

Chiến lược logic

Chiến lược đầu tiên xác định một phạm vi ngủ, đó là khi giá được chứa trong phạm vi giá của ngày giao dịch trước. Điều này cho thấy sự biến động đã giảm so với một vài ngày trước. Chúng tôi kiểm tra xem ngày hiện tại cao < cao hơn n ngày trước (thường là 4 ngày) và ngày hiện tại thấp > thấp hơn n ngày trước để đủ điều kiện là một phạm vi ngủ.

Một khi một phạm vi không hoạt động được xác định, chiến lược đặt hai lệnh đang chờ - một lệnh mua dừng gần đỉnh của phạm vi và một lệnh bán dừng gần đáy của phạm vi. Sau đó nó chờ giá phá vỡ phạm vi lên hoặc xuống. Nếu giá phá vỡ lên, lệnh mua được kích hoạt để đi dài. Nếu giá phá vỡ xuống, lệnh bán được kích hoạt để đi ngắn.

Sau khi vào, lệnh dừng lỗ và lấy lợi nhuận được đặt. Lệnh dừng lỗ kiểm soát rủi ro giảm và lấy lợi nhuận đóng giao dịch để kiếm lợi nhuận. Lệnh dừng lỗ được đặt ở khoảng cách % so với giá nhập như được xác định trong các tham số rủi ro. Lệnh lấy lợi nhuận được đặt ở khoảng cách bằng với kích thước phạm vi ngủ vì chúng tôi mong đợi giá sẽ di chuyển tương tự như biến động trước đó.

Cuối cùng, mô hình định kích thước vị trí phân số cố định quản lý kích thước giao dịch. Nó tăng kích thước cho lợi nhuận và giảm kích thước cho lỗ để cải thiện lợi nhuận điều chỉnh rủi ro.

Ưu điểm

Những lợi thế của chiến lược này là:

  1. Nhận được xu hướng sắp tới bằng cách sử dụng biến động giảm như tín hiệu.

  2. Các lệnh hai hướng bắt được xu hướng tăng hoặc giảm.

  3. Dừng lỗ và lấy lợi nhuận kiểm soát rủi ro giao dịch duy nhất.

  4. Phân tích phân số cố định cải thiện hiệu quả vốn.

  5. Logic đơn giản dễ thực hiện.

Rủi ro

Những rủi ro cần xem xét là:

  1. Hướng thoát sai nếu phạm vi không rõ ràng.

  2. Sự đột phá có thể chỉ là một sự đảo ngược ngắn, không phải là một xu hướng lâu dài.

  3. Đánh mất rủi ro bị loại bỏ bởi những động thái lớn.

  4. Kích thước phân số cố định có thể làm tăng lỗ khi thêm vào các giao dịch thua lỗ.

  5. Hiệu suất kém nếu các thông số không được thiết lập đúng cách.

Cơ hội gia tăng

Một số cách để tăng cường chiến lược:

  1. Thêm các bộ lọc như sự phân kỳ để tránh những sự đột phá sai.

  2. Cải thiện stop loss với trailing hoặc lệnh stop loss.

  3. Thêm bộ lọc xu hướng để tránh các mục chống xu hướng.

  4. Tối ưu hóa tỷ lệ phần cố định để cân bằng rủi ro / phần thưởng.

  5. Nhìn vào nhiều khung thời gian để cải thiện lợi thế.

  6. Sử dụng máy học để tối ưu hóa tham số tự động.

Kết luận

Chiến lược đảo ngược phạm vi ngủ có một logic rõ ràng và tiềm năng lợi nhuận. Điều chỉnh tinh tế thông qua tối ưu hóa, quản lý rủi ro và lọc tín hiệu có thể cải thiện hơn nữa tính nhất quán. Nhưng tất cả các chiến lược đảo ngược trung bình đều mang lại rủi ro vốn có và kích thước vị trí cần phải được kiểm soát. Nó phù hợp với các nhà giao dịch quen thuộc với chiến thuật đảo ngược và có nhận thức rủi ro hợp lý.


/*backtest
start: 2023-09-29 00:00:00
end: 2023-10-29 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 code is based on the Narrow Range strategy
//Interactive Broker fees are applied on this strategy
//@version=5
strategy("NARROW RANGE BACKTESTING", shorttitle="NR BACKTESTING", overlay=true, initial_capital=1000, default_qty_type=strategy.fixed, commission_type=strategy.commission.percent, commission_value=0.18)


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

//@function to print label
debugLabel(txt, color) =>
    label.new(bar_index, high, 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------------------------------------//

//Narrow Range Length 
nrLength = input.int(4, minval=2, title="Narrow Range Length", group="Strategy parameters")
//Risk Management
stopLossInput = input.float(0.5, title="Stop Loss (in percentage of reference range)", group="Strategy parameters")
//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 Janv 2020 00:00:00"), group="Backtesting Period")
endDate = input(title="End Date", defval=timestamp("1 July 2024 00:00:00"), group="Backtesting Period")


//--------------------------------VARIABLES INITIALISATION--------------------------//
strategy.initial_capital = 50000
bool nr = na
var bool long = na
var bool short = na
var float stopPriceLong = na
var float stopLossLong = na
var float takeProfitLong = na
var float stopPriceShort = na
var float stopLossShort = na
var float takeProfitShort = na
var float takeProfit = na
var float stopLoss = na
bool inRange = na
int closedtrades = strategy.closedtrades
equity = math.abs(strategy.equity - strategy.openprofit)
var float capital_ref = strategy.initial_capital
var float cashOrder = strategy.initial_capital * 0.95


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

//Checking if the date belong to the range
inRange := 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

//We check if a trade has been closed to cancel all previous orders
if closedtrades > closedtrades[1]
    strategy.cancel("Long")
    strategy.cancel("Short")
    stopPriceLong := na
    stopPriceShort := na

//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))
    strategy.close_all()
    long := na
    short := na
    stopPriceLong := na
    stopLossLong := na
    takeProfitLong := na
    stopPriceShort := na
    stopLossShort := na
    takeProfitShort := na
    takeProfit := na
    stopLoss := na

//----------------------------------FINDING NARROW RANGE DAY------------------------------------------//

// We find the Narrow Range Day
if low > low[nrLength] and high < high[nrLength]
    nr := true 


//------------------------------------STOP ORDERS--------------------------------------------//

// We handle plotting of stop orders and cancellation of other side order if one order is triggered
if strategy.position_size > 0 and not na(stopPriceLong) and not na(stopPriceShort)
    long := true
    strategy.cancel("Short")
    stopPriceLong := na
    stopPriceShort := na
    takeProfit := takeProfitLong
    stopLoss := stopLossLong
if strategy.position_size < 0 and not na(stopPriceLong) and not na(stopPriceShort)
    short := true
    strategy.cancel("Long") 
    stopPriceLong := na
    stopPriceShort := na
    takeProfit := takeProfitShort
    stopLoss := stopLossShort


//------------------------------------STOP LOSS & TAKE PROFIT--------------------------------//

// If an order is triggered we plot TP and SL
if not na(takeProfit) and not na(stopLoss) and long
    if high >= takeProfit and closedtrades == closedtrades[1] + 1
        takeProfit := na
        stopLoss := na
        long := na
    if low <= stopLoss and closedtrades == closedtrades[1] + 1
        takeProfit := na
        stopLoss := na
        long := na
if not na(takeProfit) and not na(stopLoss) and short
    if high >= stopLoss and closedtrades == closedtrades[1] + 1
        takeProfit := na
        stopLoss := na
        short := na
    if low <= takeProfit and closedtrades == closedtrades[1] + 1
        takeProfit := na
        stopLoss := na
        short := na


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

// Conditions to create two stop orders (one for Long and one for Short) and SL & TP calculation
if nr and inRange and strategy.position_size == 0
    stopPriceLong := high[4]
    takeProfitLong := high[4] + (high[4] - low[4])
    stopLossLong := high[4] - (high[4] - low[4])*stopLossInput
    qtyLong = cashOrder/stopPriceLong
    strategy.entry("Long", strategy.long, qtyLong, stop=stopPriceLong)
    strategy.exit("Exit Long", "Long", limit=takeProfitLong ,stop=stopLossLong)
    stopPriceShort := low[4]
    takeProfitShort := low[4] - (high[4] - low[4])
    stopLossShort := low[4] + (high[4] - low[4])*stopLossInput
    qtyShort = cashOrder/stopPriceShort
    strategy.entry("Short", strategy.short, qtyShort, stop=stopPriceShort)
    strategy.exit("Exit Short", "Short", limit=takeProfitShort ,stop=stopLossShort)


//--------------------------PLOTTING ELEMENT----------------------------//

plotshape(nr, "NR", shape.arrowdown, location.abovebar, color.rgb(255, 132, 0), text= "NR4", size=size.huge)
plot(stopPriceLong, "Stop Order", color.blue, 3, plot.style_linebr)
plot(stopPriceShort, "Stop Order", color.blue, 3, plot.style_linebr)
plot(takeProfit, "Take Profit", color.green, 3, plot.style_linebr)
plot(stopLoss, "Stop Loss", color.red, 3, plot.style_linebr)

Thêm nữa