Chiến lược Loft Stop

Tác giả:ChaoZhang, Ngày: 2023-10-07 16:11:45
Tags:

Tổng quan

Chiến lược này sử dụng bộ lọc Kalman để theo dõi giá và điều chỉnh động điểm dừng lỗ với đường dừng lỗ để đạt được mức dừng lỗ trượt.

Nguyên tắc

Chiến lược này sử dụng bộ lọc Kalman để theo dõi giá trong thời gian thực.

Phương trình dự đoán:

mượt = kf[1] + dk * sqrt(lợi nhuận / 10000 * 2)

Phương trình cập nhật:

kf = mượt + velo

nơi dk là lỗi dự đoán, lợi nhuận là lợi nhuận Kalman xác định độ nhạy theo dõi.

Ngoài ra, chiến lược sử dụng một đường dừng lỗ trượt để khóa lợi nhuận.

Khi dài, nếu giá tăng, đường dừng lỗ cũng di chuyển lên dần dần tiếp cận đường Kalman, với kích thước bước của downStep, chẳng hạn như 0,5%. Nếu giá giảm xuống mức dừng lỗ, mở lại vị trí và đặt khoảng cách dừng lỗ ban đầu.

Khóc cũng tương tự.

Do đó, chiến lược có thể dần dần khóa lợi nhuận theo xu hướng, với quản lý rủi ro tốt.

Ưu điểm

  1. Sử dụng bộ lọc Kalman để theo dõi giá trong thời gian thực với phản hồi nhanh.

  2. Khóa lợi nhuận với đường dừng lỗ trượt, đạt được quản lý rủi ro tốt.

  3. Chọn linh hoạt dài / ngắn hoặc chỉ dài / ngắn.

  4. Đánh giá về các loại hình tài sản khác

  5. Chuyển đổi linh hoạt để lấy lợi nhuận và dừng lỗ khi cần thiết.

Rủi ro

  1. Cài đặt tham số không chính xác của bộ lọc Kalman có thể dẫn đến việc theo dõi không ổn định.

  2. Trượt có thể kích hoạt điểm dừng lỗ sớm.

  3. Sliding stop loss không phù hợp với thị trường xu hướng mạnh, nên theo xu hướng.

  4. Stop loss có thể được kích hoạt thường xuyên trong các thị trường dao động.

Tối ưu hóa

  1. Kết hợp nhiều chỉ số hơn để tối ưu hóa thời gian nhập cảnh.

  2. Điều chỉnh bước chuyển động đường dừng lỗ dựa trên biến động thị trường.

  3. Sử dụng máy học để đào tạo các thông số dừng lỗ tối ưu.

  4. Bao gồm nhiều chỉ số rủi ro hơn để điều chỉnh kích thước vị trí một cách năng động.

Kết luận

Chiến lược loft stop sử dụng bộ lọc Kalman để theo dõi sự thay đổi giá và khóa lợi nhuận với một đường dừng lỗ trượt, đảm bảo lợi nhuận trong khi kiểm soát rủi ro. Đây là một chiến lược đáng tin cậy và dễ tối ưu hóa. Kết hợp với phán đoán xu hướng và kích thước vị trí năng động có thể đạt được hiệu suất chiến lược thậm chí tốt hơn.


/*backtest
start: 2023-09-06 00:00:00
end: 2023-10-06 00:00:00
period: 2h
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/
// © BigCoinHunter

//@version=5
// strategy(title='Loft Strategy V1', overlay=true, 
//      pyramiding=0, default_qty_type=strategy.fixed, 
//      default_qty_value=100, initial_capital=100000, 
//      currency=currency.USD, commission_value=0.05, 
//      commission_type=strategy.commission.percent, 
//      process_orders_on_close=true)

//-------------- fetch user inputs ------------------
gain = input.float(title="Kalman Gain:", defval=1.0, minval=1.0, maxval=5000.0, step=100.0)
src = input(defval=close, title='Source:')

stopPercentMax = input.float(title='Beginning Approach(%):', defval=2.0, minval=0.1, maxval=30.0, step=0.1)
stopPercentMin = input.float(title='Final Approach(%):    ', defval=0.5, minval=0.1, maxval=30.0, step=0.1)
downStep = input.float(title='Approach Decrease Step:', defval=0.005, minval=0.0, maxval = 5, step=0.005)

tp = input.float(title="Take Profit:", defval=1.5, minval=0.0, maxval=100.0, step=0.1) * 0.01
sl = input.float(title="Stop Loss:  ", defval=0.0, minval=0.0, maxval=100.0, step=0.1) * 0.01

longEntry = input.bool(defval=true, title= 'Long Entry', inline="11")
shortEntry = input.bool(defval=true, title='Short Entry', inline="11")

//---------- backtest range setup ------------
fromDay   = input.int(defval = 1, title = "From Day", minval = 1, maxval = 31)
fromMonth = input.int(defval = 1, title = "From Month", minval = 1, maxval = 12)
fromYear  = input.int(defval = 2021, title = "From Year", minval = 2010)
toDay     = input.int(defval = 30, title = "To Day", minval = 1, maxval = 31)
toMonth   = input.int(defval = 12, title = "To Month", minval = 1, maxval = 12)
toYear    = input.int(defval = 2022, title = "To Year", minval = 2010)


//------------ time interval setup -----------
start     = timestamp(fromYear, fromMonth, fromDay, 00, 00)  // backtest start window
finish    = timestamp(toYear, toMonth, toDay, 23, 59)        // backtest finish window
window()  => true // create function "within window of time"

//------- define the global variables ------
enterLongComment = "ENTER LONG"
exitLongComment = "EXIT LONG"

enterShortComment = "ENTER SHORT"
exitShortComment = "EXIT SHORT"

longTPSL = "Long TP/SL"
longTP = "Long TP"
longSL = "Long SL"
shortTPSL = "Short TP/SL"
shortTP = "Short TP"
shortSL = "Short SL"

var bool long = true
var bool stoppedOutLong = false
var bool stoppedOutShort = false
var float kf = 0.0
var float velo = 0.0

//------ kalman filter calculation --------
dk = src - nz(kf[1], src)
smooth = nz(kf[1], src) + dk * math.sqrt(gain / 10000 * 2)
velo := nz(velo[1], 0) + gain / 10000 * dk
kf := smooth + velo

//--------- calculate the loft stopLoss line ---------
var stopPercent = stopPercentMax
var stopLoss = kf - kf * (stopPercent /100)

if long == true
    stopLoss := kf - (kf * (stopPercent / 100))
    
    if long[1] == true and stopLoss <= stopLoss[1]
        stopLoss := stopLoss[1]
    else if (long[1] == true)
        stopPercent := stopPercent - downStep
        if(stopPercent < stopPercentMin)
            stopPercent := stopPercentMin
    
    if(kf < stopLoss)
        long := false
        stopPercent := stopPercentMax
        stopLoss := kf + (kf * (stopPercent / 100))
        
else
    stopLoss := kf + (kf * (stopPercent / 100))
    
    if long[1] == false and stopLoss >= stopLoss[1]
        stopLoss := stopLoss[1]
    else if(long[1] == false)
        stopPercent := stopPercent - downStep
        if(stopPercent < stopPercentMin)
            stopPercent := stopPercentMin
            
    if(kf > stopLoss)
        long := true
        stopPercent := stopPercentMax
        stopLoss := kf - (kf * (stopPercent / 100))
        
//--------- calculate the input/output points -----------
longProfitPrice  = strategy.position_avg_price * (1 + tp)     // tp -> take profit percentage
longStopPrice = strategy.position_avg_price * (1 - sl)        // sl -> stop loss percentage

shortProfitPrice  = strategy.position_avg_price * (1 - tp)
shortStopPrice = strategy.position_avg_price * (1 + sl)

//------------------- determine buy and sell points ---------------------
buySignall = window() and long  and (not stoppedOutLong)
sellSignall = window() and (not long)  and (not stoppedOutShort)

//---------- execute the strategy -----------------
if(longEntry and shortEntry)
    if long 
        strategy.entry("LONG", strategy.long, when = buySignall, comment = enterLongComment)
        stoppedOutLong := true
        stoppedOutShort := false
    else 
        strategy.entry("SHORT", strategy.short, when = sellSignall, comment = enterShortComment)
        stoppedOutLong  := false
        stoppedOutShort := true

else if(longEntry)
    strategy.entry("LONG", strategy.long,  when = buySignall, comment = enterLongComment)
    strategy.close("LONG", when = sellSignall, comment = exitLongComment)
    if long 
        stoppedOutLong := true
    else
        stoppedOutLong  := false

else if(shortEntry)
    strategy.entry("SHORT", strategy.short, when = sellSignall, comment = enterShortComment)
    strategy.close("SHORT", when = buySignall, comment = exitShortComment)
    if not long
        stoppedOutShort := true
    else
        stoppedOutShort := false
    

//----------------- take profit and stop loss -----------------
if(tp>0.0 and sl>0.0)
    if ( strategy.position_size > 0 )
        strategy.exit(id="LONG", limit=longProfitPrice, stop=longStopPrice, comment = longTPSL)

    else if ( strategy.position_size < 0 )
        strategy.exit(id="SHORT", limit=shortProfitPrice, stop=shortStopPrice, comment = shortTPSL)

else if(tp>0.0)
    if ( strategy.position_size > 0 )
        strategy.exit(id="LONG", limit=longProfitPrice, comment = longTP)

    else if ( strategy.position_size < 0 )
        strategy.exit(id="SHORT", limit=shortProfitPrice, comment = shortTP)
        
else if(sl>0.0)
    if ( strategy.position_size > 0 )
        strategy.exit(id="LONG",  stop=longStopPrice, comment = longSL)

    else if ( strategy.position_size < 0 )
        strategy.exit(id="SHORT",  stop=shortStopPrice, comment = shortSL)
        
//------------- plot charts ---------------------
lineColor1 = long ? color.green : color.red
lineColor2 = long ? color.aqua : color.fuchsia

kalmanLine = plot(kf, color=lineColor1, linewidth=3, title = "Kalman Filter")
stopLine = plot(stopLoss, color=lineColor2, linewidth=2, title = "Stop Loss Line")






Thêm nữa