Chiến lược giao dịch ngắn hạn dựa trên sự đảo ngược của đường trung bình động


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

Chiến lược giao dịch ngắn hạn dựa trên sự đảo ngược của đường trung bình động

Tổng quan

Chiến lược đường trung bình đảo ngược là một chiến lược giao dịch đường ngắn dựa trên đường trung bình đảo ngược. Nó kết hợp nhiều chỉ số như Brin Band, RSI, CCI để nắm bắt các thay đổi trong tình hình đường ngắn của thị trường tài chính để đạt được mục tiêu giao dịch thấp hơn hoặc cao hơn.

Chiến lược này chủ yếu được sử dụng cho các loại có tính thanh khoản cao như chỉ số cổ phiếu, ngoại hối và kim loại quý. Nó tìm kiếm tối đa hóa lợi nhuận cho mỗi giao dịch, đồng thời kiểm soát tỷ lệ lợi nhuận rủi ro cho giao dịch tổng thể.

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

  1. Sử dụng các vùng Brin để xác định giá trị của giá. Khi giá gần vùng Brin, hãy xem xét giảm giá và khi giá gần vùng Brin, hãy xem xét tăng giá.

  2. Kết hợp với chỉ số RSI để xác định xem có quá mua hay quá bán không. Chỉ số RSI có thể xác định hiệu quả tình trạng quá mua quá bán.

  3. Chỉ số CCI đánh giá tín hiệu đảo ngược giá. Chỉ số CCI nhạy cảm với các trường hợp bất thường, có thể nắm bắt hiệu quả cơ hội đảo ngược giá.

  4. Giá vượt qua đường trung bình 5 ngày nhiều hơn, dưới đường trung bình 5 ngày trống. Vị trí đường trung bình đại diện cho phạm vi giá chính hiện tại, và mối quan hệ giữa giá và đường trung bình phản ánh sự thay đổi xu hướng tiềm ẩn.

  5. Sau khi nhận được tín hiệu, bạn có thể nhanh chóng thanh toán để lấy lợi nhuận. Đặt lệnh dừng lỗ và rút ra theo tình huống rút lui để đạt được tỷ lệ thắng cao.

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

  1. Kết hợp nhiều chỉ số để tăng độ chính xác tín hiệu

Chiến lược đường trung bình đảo ngược sử dụng nhiều chỉ số cùng một lúc như Brin, RSI, CCI. Các chỉ số này rất nhạy cảm với biến động giá, sử dụng kết hợp có thể cải thiện độ chính xác của tín hiệu và giảm tín hiệu sai.

  1. Những quy định nghiêm ngặt để tránh bị ảnh hưởng nặng nề

Chiến lược yêu cầu tín hiệu chỉ số và giá xuất hiện đồng bộ, tránh bị sai lệch bởi chỉ số đơn lẻ. Đồng thời yêu cầu giá đã bị đảo ngược rõ ràng, giảm rủi ro liên quan.

  1. Cơ chế ngăn chặn thiệt hại hiệu quả, kiểm soát tổn thất đơn lẻ

Bất cứ khi nào bạn thực hiện nhiều lệnh giảm giá, chiến lược sẽ thiết lập một đường dừng lỗ nghiêm ngặt hơn. Một khi giá vượt qua đường dừng lỗ theo hướng không thuận lợi, chiến lược sẽ dừng lại nhanh chóng, tránh tổn thất lớn một lần.

  1. Giảm bớt chi phí, tối đa hóa lợi nhuận mỗi lần

Chiến lược sẽ thiết lập hai mục tiêu dừng để đạt được lợi nhuận theo từng bước. Đồng thời, sau khi dừng lại, hãy sử dụng các bước nhỏ để điều chỉnh theo dõi dừng lỗ và mở rộng mỗi khoảng cách lợi nhuận.

Phân tích rủi ro

  1. Giá cả biến động mạnh, gây ra lỗ hổng

Trong trường hợp giá biến động mạnh, đường dừng có thể bị phá vỡ, gây ra tổn thất không cần thiết. Điều này thường xảy ra trong biến động bất thường của giá do sự kiện lớn.

Có thể đối phó với rủi ro này bằng cách mở rộng mức độ dừng lỗ, đồng thời tránh hoạt động trong các sự kiện lớn.

  1. Bị đuổi theo quá mạnh, không thể quay lại

Khi giá tăng quá mạnh, giá thường tăng quá nhanh và không thể đảo ngược kịp thời. Nếu bạn tiếp tục ở vị trí này, bạn có thể sẽ gặp rủi ro khi tiếp tục giảm giá.

Trong trường hợp này, nên chờ đợi một thời gian, và chỉ xem xét can thiệp khi tăng giá giảm rõ rệt.

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

  1. Tối ưu hóa tham số chỉ số, nâng cao độ chính xác tín hiệu

Bạn có thể kiểm tra kết quả phản hồi dưới các tổ hợp tham số khác nhau để chọn tham số tốt nhất. Ví dụ: tham số có thể tối ưu hóa RSI, tham số CCI, v.v.

  1. Kết hợp các chỉ số năng lượng để xác định thời gian thực sự thay đổi

Có thể thêm chỉ số hiệu lực tương đương với khối lượng giao dịch hoặc băng thông Brin. Điều này có thể tránh tạo ra tín hiệu sai khi giá chỉ điều chỉnh nhỏ.

  1. Tối ưu hóa chiến lược dừng lỗ để mở rộng lợi nhuận

Có thể thử nghiệm các điểm dừng khác nhau để tối đa hóa lợi nhuận mỗi lần. Đồng thời, bạn cũng phải cân bằng rủi ro để tránh dừng lỗ bị kích hoạt dễ dàng.

Tóm tắt

Chiến lược đường trung bình đảo ngược sử dụng nhiều chỉ số, có tín hiệu chính xác, quy định hoạt động và rủi ro có thể kiểm soát được. Nó phù hợp với các giống có độ nhạy cao đối với sự thay đổi của thị trường, có tính thanh khoản mạnh mẽ, có thể nắm bắt cơ hội đảo ngược giá giữa vùng Brin và đường trung bình quan trọng, để đạt được mục tiêu giao dịch giá thấp.

Trong ứng dụng thực tế, vẫn cần chú ý đến việc tối ưu hóa các tham số chỉ số, đồng thời kết hợp với số lượng chỉ số có thể xác định thời điểm thực sự đảo ngược. Ngoài ra, quản lý rủi ro tốt để đối phó với biến động giá mạnh. Nếu được sử dụng đúng cách, chiến lược này có thể thu được lợi nhuận Alpha tương đối ổn định.

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

//@version=4


// >>>>>strategy name
strategy(title = "CCI-RSI MR", shorttitle = "CCI-RSI MR", overlay = true)

// >>>>input variables

// 1. risk per trade as % of initial capital
risk_limit = input(title="Risk Limit (%)", type=input.float, minval=0.1, defval=2.0, step=0.1)

// 2. drawdown
Draw_down = input(title="Max Drawdown (x ATR)", type=input.float, minval=0.5, maxval=10, defval=2.0, step=0.1)

// 3. type of stop loss to be used
original_sl_type  = input(title="SL Based on", defval="Close Price", options=["Close Price","Last Traded Price"])

// 4. entry signal validity for bollinger strategies
dist_from_signal= input(title="Entry distance from signal", type=input.integer, minval=1, maxval=20, defval=3, step=1)

// 5. multiple exit points
exit_1_pft_pct          = input(title="1st exit when reward is", type=input.float, minval=0.5, maxval=100, defval=1.0, step=0.1)
exit_1_qty_pct          = input(title="1st exit quantity %", type=input.float, minval=1, maxval=100, defval=100, step=5)
exit_2_pft_pct          = input(title="2nd exit when reward is", type=input.float, minval=0.5, maxval=100, defval=1.5, step=0.1)
sl_trail_pct            = input(title="Trailing SL compared to original SL", type=input.float, minval=0.5, maxval=100, defval=0.5, step=0.5)

//show signal bool
plotBB = input(title="Show BB", type=input.bool, defval=true)
plotSignals  = input(title="Show Signals", type=input.bool, defval=true)

// 6. date range to be used for backtesting
fromMonth = input(defval = 1,    title = "From Month",      type = input.integer, minval = 1, maxval = 12)
fromDay   = input(defval = 1,    title = "From Day",        type = input.integer, minval = 1, maxval = 31)
fromYear  = input(defval = 1990, title = "From Year",       type = input.integer, minval = 1970)
thruMonth = input(defval = 1,    title = "Thru Month",      type = input.integer, minval = 1, maxval = 12)
thruDay   = input(defval = 1,    title = "Thru Day",        type = input.integer, minval = 1, maxval = 31)
thruYear  = input(defval = 2022, title = "Thru Year",       type = input.integer, minval = 1970)

start     = timestamp(fromYear, fromMonth, fromDay, 00, 00)        // backtest start window
finish    = timestamp(thruYear, thruMonth, thruDay, 23, 59)        // backtest finish window
window()  => true

// >>>>>strategy variables

//input variables 
current_high = highest(high, 5)     // swing high (5 period)
current_low = lowest(low, 5)        // swing low (5 period)
current_ma = sma(close, 5)          // Simple Moving average (5 period)
atr_length = atr(20)                // ATR (20 period)  
CCI = cci(close,20)                 // CCI (20 period)
RSI = rsi(close,14)                 // RSI (14 period)
RSI_5 = sma (RSI, 5)                // Simple moving average of RSI (5 period)


// 1. for current candle

long_entry              = false 
short_entry             = false
risk_reward_ok          = false
sl_hit_flag             = false
tsl_hit_flag            = false
sl_cross                = false

// 2. across candles

var RSI_short           = false     //short signal boolean
var RSI_long            = false     //long signal boolean
var cci_sell            = false     //sellsignal crossunder boolean
var cci_buy             = false     //buy signal crossover boolean
var bar_count_long      = 0         // Number of bars after a long signal 
var bar_count_short     = 0         // Number of bars after a short signal
var candles_on_trade    = 0         
var entry_price         = 0.00
var sl_price            = 0.00
var qty                 = 0
var exit_1_qty          = 0
var exit_2_qty          = 0
var exit_1_price        = 0.0
var exit_2_price        = 0.0
var hold_high           = 0.0       // variable used to calculate Trailing sl
var hold_low            = 0.0       // variable used to calculate Trailing sl
var tsl_size            = 0.0       // Trailing Stop loss size(xR)
var sl_size             = 0.0       // Stop loss size (R)
var tsl_price           = 0.0       //Trailing stoploss price


// >>>>>strategy conditions.
// Bollinger bands (2 std)
[mBB0,uBB0,lBB0] = bb(close,20,2)
uBB0_low= lowest(uBB0,3) // lowest among upper BB of past 3 periods
lBB0_high= highest(lBB0,3) //highest among upper BB of past 3 periods


//RSI and CCI may not necessarily crossunder on the same candle
t_sell_RSI = sum( crossunder(RSI,RSI_5)? 1 : 0, 2) == 1 // checks if crossunder has happened in the last 3 candles (including the current candle)
t_sell_CCI = sum( crossunder(CCI,100)? 1 : 0, 2) == 1 //and (CCI >50)
t_buy_RSI  = sum( crossover(RSI,RSI_5)? 1 : 0, 2) == 1  //checks if crossover has happened in the last 3 candles (including the current candle)
t_buy_CCI  = sum( crossover(CCI,-100) ? 1 : 0, 2) == 1 //and (CCI<-50)

// CONDITIONS FOR A SELL signal
if t_sell_RSI and t_sell_CCI and (current_high >= uBB0_low) 
    cci_sell := true
    bar_count_short := 0
 
if  cci_sell and strategy.position_size ==0 
    bar_count_short := bar_count_short + 1
    
if  cci_sell and bar_count_short<= dist_from_signal and close <= current_ma  and strategy.position_size ==0
    RSI_short := true

//conditions for a BUY signal
if t_buy_RSI and t_buy_CCI and (current_low <= lBB0_high) // or current_low_close <= lBB01_high)
    cci_buy := true
    bar_count_long := 0

if  cci_buy and strategy.position_size ==0 
    bar_count_long := bar_count_long + 1
    
if  cci_buy and  bar_count_long<= dist_from_signal and close >= current_ma and strategy.position_size ==0
    RSI_long := true

if RSI_long and RSI_short
    RSI_long := false
    RSI_short := false



// >>>>>entry and target specifications

if strategy.position_size == 0 and RSI_short 
    short_entry         := true
    entry_price         := close
    sl_price            := current_high + syminfo.mintick // (swing high + one tick) is the stop loss
    sl_size             := abs(entry_price - sl_price)
    candles_on_trade    := 0
    tsl_size            := abs(entry_price - sl_price)*sl_trail_pct // Here sl_trail_pct is the multiple of R which is used to calculate TSL size

if strategy.position_size == 0 and RSI_long 
    long_entry          := true
    entry_price         := close
    sl_price            := current_low -  syminfo.mintick //(swing low - one tick) is the stop loss
    candles_on_trade    := 0
    sl_size             := abs(entry_price - sl_price)
    tsl_size            := abs(entry_price - sl_price)*sl_trail_pct // Here sl_trail_pct is the multiple of R which is used to calculate TSL size
    
if long_entry and short_entry
    long_entry          := false
    short_entry         := false
    
    
// >>>>risk evaluation criteria
    
//>>>>> quantity determination and exit point specifications.
    
if (long_entry or short_entry) and strategy.position_size == 0 // Based on our risk (R), no.of lots is calculated by considering a risk per trade limit formula
    qty                 := round((strategy.equity) * (risk_limit/100)/(abs(entry_price - sl_price)*syminfo.pointvalue))
    exit_1_qty          := round(qty * (exit_1_qty_pct/100))
    exit_2_qty          := qty - (exit_1_qty)
    if long_entry
        exit_1_price    := entry_price + (sl_size * exit_1_pft_pct) 
        exit_2_price    := entry_price + (sl_size * exit_2_pft_pct)
    if short_entry
        exit_1_price    := entry_price - (sl_size * exit_1_pft_pct) 
        exit_2_price    := entry_price - (sl_size * exit_2_pft_pct)
        
        
// trail SL after 1st target is hit
if abs(strategy.position_size) == 0
    hold_high   := 0
    hold_low    := 0

if strategy.position_size > 0 and high > exit_1_price
    if high > hold_high or hold_high == 0
        hold_high    := high
    tsl_price        := hold_high - tsl_size
    

if strategy.position_size < 0 and low < exit_1_price
    if low  < hold_low or hold_low == 0
        hold_low     := low
    tsl_price        := hold_low + tsl_size

    
//>>>> entry conditons

if long_entry and strategy.position_size == 0
    strategy.cancel("BUY", window())   // add another window condition which considers day time (working hours)
    strategy.order("BUY", strategy.long, qty, comment="BUY @ "+ tostring(entry_price),when=window())

if short_entry and strategy.position_size == 0
    strategy.cancel("SELL", window()) // add another window condition which considers day time (working hours)
    strategy.order("SELL", strategy.short, qty, comment="SELL @ "+ tostring(entry_price),when=window())

//>>>> exit conditons

tsl_hit_flag     := false

//exit at tsl
if strategy.position_size > 0 and close < tsl_price  and abs(strategy.position_size)!=qty 
    strategy.order("EXIT at TSL", strategy.short, abs(strategy.position_size),  comment="EXIT TSL @ "+ tostring(close))
    RSI_short                := false   
    RSI_long                 := false
    bar_count_long            := 0
    bar_count_short           := 0
    tsl_hit_flag              := true
    cci_sell := false
    cci_buy := false
    strategy.cancel("EXIT 1", true)
    strategy.cancel("EXIT 2", true)
    strategy.cancel("Exit Drawd",true)
    strategy.cancel("EXIT at SL",true)

if strategy.position_size < 0 and close > tsl_price  and abs(strategy.position_size)!=qty 
    strategy.order("EXIT at TSL", strategy.long, abs(strategy.position_size), comment="EXIT TSL @ "+ tostring(close))
    RSI_short                := false   
    RSI_long                 := false
    bar_count_long            := 0
    bar_count_short           := 0   
    tsl_hit_flag              := true
    cci_sell := false
    cci_buy := false
    strategy.cancel("EXIT 1", true)
    strategy.cancel("EXIT 2", true)
    strategy.cancel("Exit Drawd",true)
    strategy.cancel("EXIT at SL",true)

//>>>>exit at sl
    
if strategy.position_size > 0 and original_sl_type == "Close Price" and close < sl_price and abs(strategy.position_size)==qty
    strategy.cancel("EXIT at SL", true)
    strategy.order("EXIT at SL", strategy.short, abs(strategy.position_size),stop= sl_price,  comment="EXIT SL @ "+ tostring(close))
    RSI_short                := false   
    RSI_long                 := false
    bar_count_long            := 0
    bar_count_short           := 0
    cci_buy := false
    cci_sell := false
    sl_hit_flag               := true
    strategy.cancel("EXIT 1", true)
    strategy.cancel("EXIT 2", true)
    strategy.cancel("Exit Drawd",true)
    strategy.cancel("EXIT at TSL",true)
    

if strategy.position_size < 0 and original_sl_type == "Close Price" and close > sl_price and abs(strategy.position_size)==qty
    strategy.cancel("EXIT at SL", true)
    strategy.order("EXIT at SL", strategy.long, abs(strategy.position_size), stop = sl_price, comment="EXIT SL @ "+ tostring(close))
    RSI_short               := false   
    RSI_long                := false
    bar_count_long           := 0
    bar_count_short          := 0   
    cci_buy := false
    cci_sell := false
    sl_hit_flag              := true
    strategy.cancel("EXIT 1", true)
    strategy.cancel("EXIT 2", true)
    strategy.cancel("Exit Drawd",true)
    strategy.cancel("EXIT at TSL",true)
    

    
//>>>>>for ltp sl setting

if strategy.position_size > 0 and original_sl_type == "Last Traded Price" and abs(strategy.position_size) ==qty
    strategy.order("EXIT at SL", strategy.short, abs(strategy.position_size),stop= sl_price,  comment="EXIT SL @ "+ tostring(close))
    RSI_short              := false   
    RSI_long               := false
    bar_count_long          := 0
    bar_count_short         := 0
    cci_buy := false
    cci_sell := false
    strategy.cancel("EXIT 1", true)
    strategy.cancel("EXIT 2", true)
    strategy.cancel("Exit Drawd",true)
    strategy.cancel("EXIT at TSL",true)
    
if strategy.position_size < 0 and original_sl_type == "Last Traded Price" and abs(strategy.position_size) ==qty
    strategy.order("EXIT at SL", strategy.long, abs(strategy.position_size), stop = sl_price, comment="EXIT SL @ "+ tostring(close))
    RSI_short              := false   
    RSI_long               := false
    bar_count_long          := 0
    bar_count_short         := 0   
    cci_buy := false
    cci_sell := false
    strategy.cancel("EXIT 1", true)
    strategy.cancel("EXIT 2", true)
    strategy.cancel("Exit Drawd",true)
    strategy.cancel("EXIT at TSL",true)

//>>>>>exit at target

if strategy.position_size > 0 and abs(strategy.position_size) == qty and not tsl_hit_flag
    strategy.order("EXIT 1", strategy.short, exit_1_qty, limit=exit_1_price, comment="EXIT TG1 @ "+ tostring(exit_1_price))
    strategy.cancel("Exit Drawd",true)
    cci_sell := false
    cci_buy := false

if strategy.position_size > 0 and abs(strategy.position_size) < qty and abs(strategy.position_size) != qty and not tsl_hit_flag
    strategy.order("EXIT 2", strategy.short, exit_2_qty, limit=exit_2_price, comment="EXIT TG2 @ "+ tostring(exit_2_price))
    RSI_short := false   
    RSI_long  := false
    bar_count_long := 0
    bar_count_short := 0
    cci_buy := false
    cci_sell := false
    strategy.cancel("Exit Drawd",true)
    strategy.cancel("EXIT at SL", true)

if strategy.position_size < 0 and abs(strategy.position_size) == qty and not tsl_hit_flag
    strategy.order("EXIT 1", strategy.long, exit_1_qty, limit=exit_1_price, comment="EXIT TG1 @ "+ tostring(exit_1_price))
    strategy.cancel("Exit Drawd",true)
    cci_buy := false
    cci_sell := false

if strategy.position_size < 0 and abs(strategy.position_size) < qty and abs(strategy.position_size) != qty 
    strategy.order("EXIT 2", strategy.long, exit_2_qty, limit=exit_2_price, comment="EXIT TG2 @ "+ tostring(exit_2_price))
    RSI_short := false   
    RSI_long  := false
    bar_count_long := 0
    bar_count_short := 0  
    cci_buy := false
    cci_sell := false
    strategy.cancel("Exit Drawd",true)
    strategy.cancel("EXIT at SL", true)
    
//>>>>>>drawdown execution

if strategy.position_size < 0 and original_sl_type == "Close Price" and not tsl_hit_flag  
    strategy.cancel("Exit Drawd",true)
    strategy.order("Exit Drawd", strategy.long, abs(strategy.position_size), stop= (entry_price + Draw_down*atr_length)  ,comment="Drawdown exit S")
    RSI_short            := false   
    RSI_long             := false
    bar_count_long        := 0
    bar_count_short       := 0
    cci_buy := false
    cci_sell := false
   
    
if strategy.position_size > 0 and original_sl_type == "Close Price" and not tsl_hit_flag and not sl_hit_flag 
    strategy.cancel("Exit Drawd",true)
    strategy.order("Exit Drawd", strategy.short, abs(strategy.position_size), stop= (entry_price - Draw_down*atr_length)  ,comment="Drawdown exit B")
    RSI_short           := false   
    RSI_long            := false
    bar_count_long       := 0
    bar_count_short      := 0
    cci_buy := false
    cci_sell := false
    
//>>>>to add sl hit sign  

if strategy.position_size != 0 and sl_hit_flag //For symbols on chart
    sl_cross := true

//>>>>>cancel all pending orders if the trade is booked

strategy.cancel_all(strategy.position_size == 0 and not (long_entry or short_entry))

//>>>>plot indicators
p_mBB = plot(plotBB ? mBB0 : na, color=color.teal)
p_uBB = plot(plotBB ? uBB0 : na, color=color.teal, style=plot.style_stepline)
p_lBB = plot(plotBB ? lBB0 : na, color=color.teal, style=plot.style_stepline)


plot(sma(close,5), color=color.blue, title="MA")





//>>>>plot signals

plotshape(plotSignals and RSI_short, style=shape.triangledown, location=location.abovebar, color=color.red)
plotshape(plotSignals and RSI_long, style=shape.triangleup, location=location.belowbar, color=color.green)
plotshape(sl_cross, text= "Stoploss Hit",size= size.normal,style=shape.xcross , location=location.belowbar, color=color.red)

//>>>>plot signal high low
if strategy.position_size != 0
    candles_on_trade := candles_on_trade + 1

if strategy.position_size != 0 and candles_on_trade == 1
    line.new(x1=bar_index[1], y1=high[1], x2=bar_index[0], y2=high[1], color=color.black, width=2)
    line.new(x1=bar_index[1], y1=low[1],  x2=bar_index[0], y2=low[1],  color=color.black, width=2)



//>>>>end of program