Chiến lược thoái lui giao cắt SMA dừng lỗ theo vị trí động

SMA MA RRR TP SL
Ngày tạo: 2025-02-21 13:51:50 sửa đổi lần cuối: 2025-02-21 13:51:50
sao chép: 0 Số nhấp chuột: 338
2
tập trung vào
319
Người theo dõi

Chiến lược thoái lui giao cắt SMA dừng lỗ theo vị trí động Chiến lược thoái lui giao cắt SMA dừng lỗ theo vị trí động

Tổng quan

Chiến lược này là một hệ thống giao dịch tự động dựa trên giao điểm và quản lý vị trí động. Nó sử dụng đường trung bình di chuyển đơn giản 50 và 200 ngày (SMA) làm chỉ số chính, kết hợp với cơ chế điều chỉnh vị trí động và theo dõi dừng lỗ để tìm kiếm cơ hội giao dịch trong xu hướng thị trường.

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

Chiến lược hoạt động dựa trên các nguyên tắc cốt lõi sau:

  1. Tín hiệu nhập dựa trên giá và đường trung bình 50 ngày, đồng thời tham khảo vị trí tương đối của đường trung bình 50 ngày và đường trung bình 200 ngày để đánh giá xu hướng lớn
  2. Khi giá phá vỡ từ hướng dưới đường trung bình, kích hoạt nhiều tín hiệu; ngược lại, kích hoạt tín hiệu trống
  3. Quản lý vị trí sử dụng cơ chế điều chỉnh động, tăng số lượng giữ vị trí khi tài khoản kiếm được hơn 4000
  4. Hạn lỗ sử dụng cơ chế theo dõi dừng lỗ, động điều chỉnh vị trí dừng lỗ khi lợi nhuận tăng
  5. Tỷ lệ lợi nhuận rủi ro được thiết lập là 1: 2.5, đảm bảo lợi nhuận dự kiến cho mỗi giao dịch lớn hơn rủi ro

Lợi thế chiến lược

  1. Logic giao dịch rõ ràng, kết hợp các chỉ số kỹ thuật và hành vi giá để đánh giá thời gian nhập cảnh
  2. Sử dụng quản lý vị trí động, có thể tăng quy mô giao dịch khi lợi nhuận và cải thiện hiệu quả sử dụng vốn
  3. Theo dõi các cơ chế dừng lỗ có thể khóa lợi nhuận một cách hiệu quả và tránh rút tiền lớn
  4. Thiết lập bộ lọc thời gian giao dịch, chỉ hoạt động trong thời gian giao dịch chính, tránh rủi ro trong thời gian thiếu thanh khoản
  5. Có cơ chế kiểm soát rủi ro tốt, bao gồm mục tiêu dừng lỗ, lợi nhuận và quản lý vị trí

Rủi ro chiến lược

  1. Có thể kích hoạt các tín hiệu phá vỡ giả thường xuyên trong thị trường bất ổn, dẫn đến dừng liên tục
  2. Quản lý vị trí động có thể dẫn đến tổn thất lớn khi thị trường đột ngột biến đổi
  3. Hệ thống dựa trên đường thẳng có thể bị chậm phản ứng trong thị trường biến động nhanh
  4. Tỷ lệ lợi nhuận rủi ro cố định có thể bỏ lỡ một số cơ hội trong xu hướng lớn tiềm năng
  5. Giới hạn thời gian giao dịch có thể bỏ lỡ cơ hội thị trường quan trọng

Hướng tối ưu hóa chiến lược

  1. Có thể giới thiệu chỉ số biến động, điều chỉnh các tham số động theo môi trường thị trường khác nhau
  2. Xem xét thêm các chỉ số cảm xúc thị trường để tăng độ chính xác của tín hiệu đầu vào
  3. Tối ưu hóa các tham số tracking stop loss để phù hợp hơn với các môi trường thị trường khác nhau
  4. Tăng phân tích chu kỳ thời gian đa dạng, tăng sự ổn định của hệ thống giao dịch
  5. Tiến hành phân tích khối lượng giao thông để tăng độ tin cậy tín hiệu

Tóm tắt

Chiến lược này được xây dựng một hệ thống giao dịch tương đối hoàn chỉnh bằng cách kết hợp hệ thống đường thẳng, quản lý vị trí động và theo dõi các cơ chế dừng lỗ. Ưu điểm của chiến lược là có logic giao dịch rõ ràng và cơ chế kiểm soát rủi ro tốt, nhưng cũng có một số nơi cần được tối ưu hóa. Bằng cách cải thiện và tối ưu hóa liên tục, chiến lược này có khả năng hoạt động tốt hơn trong giao dịch thực tế.

Mã nguồn chiến lược
/*backtest
start: 2024-02-22 00:00:00
end: 2025-02-19 08:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"SOL_USDT"}]
*/

//@version=5
strategy("15m - Rebound 50SMA with Dynamic Lots & Trailing Stop, RRR 2:1, Date Filter (Closed Bars Only)", 
     overlay=true, 
     initial_capital=50000, 
     default_qty_type=strategy.fixed, 
     default_qty_value=1, 
     pyramiding=0, 
     calc_on_order_fills=true)

// ===== INPUTS =====
sma50Period  = input.int(50, "50 SMA Period", minval=1)
sma200Period = input.int(200, "200 SMA Period", minval=1)

// ===== CALCULATE SMAs =====
sma50  = ta.sma(close, sma50Period)
sma200 = ta.sma(close, sma200Period)

// ===== PLOT SMAs =====
plot(sma50, color=color.red, title="50 SMA")
plot(sma200, color=color.blue, title="200 SMA")

// ===== DEFINE TRADING SESSIONS =====
// Trading is allowed 15 minutes after market open:
//   - New York: 09:45–16:00 (America/New_York)
//   - London:   08:15–16:00 (Europe/London)
nySession     = not na(time("15", "0945-1600", "America/New_York"))
londonSession = not na(time("15", "0815-1600", "Europe/London"))
inSession     = nySession or londonSession

// ===== DEFINE DATE RANGE =====
// Only allow orders on or after January 1, 2024.
// (We include seconds in the timestamp for proper parsing.)
startDate   = timestamp("UTC", 2024, 1, 1, 0, 0, 0)
inDateRange = time >= startDate

// ===== DEFINE ENTRY CONDITIONS =====
// ----- LONG ENTRY CONDITION -----
// A long entry is triggered when:
//   - The previous candle closed below the 50 SMA and the current candle closes above it,
//   - And the 50 SMA is above the 200 SMA.
longCondition = (close[1] < sma50[1]) and (close > sma50) and (sma50 > sma200)

// ----- SHORT ENTRY CONDITION -----
// A short entry is triggered when:
//   - The previous candle closed above the 50 SMA and the current candle closes below it,
//   - And the 50 SMA is below the 200 SMA.
shortCondition = (close[1] > sma50[1]) and (close < sma50) and (sma50 < sma200)

// ===== DEBUG PLOTS =====
plotshape(longCondition and barstate.isconfirmed, title="Long Signal", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.tiny)
plotshape(shortCondition and barstate.isconfirmed, title="Short Signal", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.tiny)

// ===== VARIABLES FOR STOP LOSS MANAGEMENT =====
// For long positions.
var float initialLongStop = na   // Set at entry: low of the rebound candle.
var float trailStopLong   = na   // Updated trailing stop for long.
// For short positions.
var float initialShortStop = na  // Set at entry: high of the rebound candle.
var float trailStopShort   = na  // Updated trailing stop for short.

// ===== DYNAMIC LOT SIZE =====
// If current profit (strategy.equity - 50000) exceeds 4000, lot size becomes 3; otherwise, 2.
lotSize = (strategy.equity - 50000 > 4000) ? 3 : 2

// ===== ENTRY LOGIC (EXECUTED ON CONFIRMED BARS) =====
if barstate.isconfirmed and inSession and inDateRange and longCondition and strategy.position_size <= 0
    initialLongStop := low
    trailStopLong   := initialLongStop
    if strategy.position_size < 0
        strategy.close("Short", comment="Close Short before Long")
    // Submit a market order entry (no offset).
    strategy.entry("Long", strategy.long, qty=lotSize, comment="Enter Long")
    
if barstate.isconfirmed and inSession and inDateRange and shortCondition and strategy.position_size >= 0
    initialShortStop := high
    trailStopShort   := initialShortStop
    if strategy.position_size > 0
        strategy.close("Long", comment="Close Long before Short")
    // Submit a market order entry (no offset).
    strategy.entry("Short", strategy.short, qty=lotSize, comment="Enter Short")
    
// ===== TRAILING STOP LOGIC & EXIT ORDERS (ON CLOSED BARS) =====

if barstate.isconfirmed and strategy.position_size > 0
    // For Long Positions:
    floatingProfitLong = (close - strategy.position_avg_price) / syminfo.mintick
    newTrailLong = trailStopLong  // Default: no change.
    if floatingProfitLong >= 20 and floatingProfitLong < 30
        newTrailLong := initialLongStop + 5 * syminfo.mintick
    else if floatingProfitLong >= 31 and floatingProfitLong < 40
        newTrailLong := initialLongStop + 10 * syminfo.mintick
    else if floatingProfitLong >= 41 and floatingProfitLong < 50
        newTrailLong := initialLongStop + 15 * syminfo.mintick
    // Update trailing stop only if the new value is more favorable.
    trailStopLong := math.max(trailStopLong, newTrailLong)
    
    longRisk = strategy.position_avg_price - trailStopLong
    tpLong   = strategy.position_avg_price + 2.5 * longRisk
    strategy.exit("Exit Long", from_entry="Long", stop=trailStopLong, limit=tpLong)

if barstate.isconfirmed and strategy.position_size < 0
    // For Short Positions:
    floatingProfitShort = (strategy.position_avg_price - close) / syminfo.mintick
    newTrailShort = trailStopShort  // Default: no change.
    if floatingProfitShort >= 20 and floatingProfitShort < 30
        newTrailShort := initialShortStop - 5 * syminfo.mintick
    else if floatingProfitShort >= 31 and floatingProfitShort < 40
        newTrailShort := initialShortStop - 10 * syminfo.mintick
    else if floatingProfitShort >= 41 and floatingProfitShort < 50
        newTrailShort := initialShortStop - 15 * syminfo.mintick
    // Update trailing stop only if the new value is more favorable.
    trailStopShort := math.min(trailStopShort, newTrailShort)
    
    shortRisk = trailStopShort - strategy.position_avg_price
    tpShort = strategy.position_avg_price - 2.5 * shortRisk
    strategy.exit("Exit Short", from_entry="Short", stop=trailStopShort, limit=tpShort)