Chiến lược đảo ngược trung bình di chuyển kép

Tác giả:ChaoZhang, Ngày: 2023-12-25 13:24:14
Tags:

img

Tổng quan

Chiến lược đảo ngược trung bình di chuyển kép là một chiến lược giao dịch định lượng sử dụng trung bình di chuyển kép để xác định xu hướng ngắn hạn và dài hạn. Chiến lược kết hợp trung bình di chuyển đơn giản 10 ngày (SMA) và SMA 200 ngày để tận dụng những đợt lùi ngắn hạn trong xu hướng tăng dài hạn cơ bản. Nó cũng có các cơ chế theo xu hướng và quản lý rủi ro.

Chiến lược logic

Chiến lược đảo ngược trung bình di chuyển kép dựa trên các giả định sau:

  1. Đường SMA 200 ngày xác định xu hướng dài hạn hiện hành của thị trường. Khi giá vượt quá đường 200 ngày, nó báo hiệu rằng thị trường đang trong xu hướng tăng dài hạn.

  2. Đường SMA 10 ngày chỉ ra sự giảm giá ngắn hạn. Khi giá giảm xuống dưới đường 10 ngày, nó cho thấy sự giảm giá tạm thời đã xảy ra.

  3. Trong một xu hướng tăng giá đang diễn ra, bất kỳ sự rút lui ngắn hạn nào cũng có thể được xem là một cơ hội mua để bắt kịp sự phục hồi tăng.

Dựa trên các giả định trên, các tín hiệu giao dịch được tạo như sau:

  1. Khi giá đóng vượt trên đường SMA 200 ngày và đồng thời vượt dưới đường SMA 10 ngày, nó kích hoạt tín hiệu mua vì nó cho thấy xu hướng dài hạn vẫn tích cực nhưng đã có một sự rút lui ngắn hạn.

  2. Nếu giá tăng trở lại trên đường SMA 10 ngày khi ở vị trí dài, xu hướng ngắn hạn đã đảo ngược nên vị trí sẽ được đóng ngay lập tức.

  3. Bất cứ khi nào có sự suy thoái lớn (vượt quá ngưỡng đã xác định trước), nó cung cấp một cơ hội để mua giảm như một tín hiệu ngược lại.

Với thiết kế này, chiến lược nhằm mục đích tận dụng hiệu quả các snapback tăng trong thời gian xu hướng tăng liên tục trong khi kiểm soát rủi ro bằng cách dừng lỗ.

Ưu điểm

Chiến lược đảo ngược trung bình di chuyển kép có những lợi thế chính sau:

  1. Lý thuyết chiến lược là đơn giản và dễ hiểu.
  2. Các bộ lọc trung bình động kép xác định hiệu quả xu hướng ngắn hạn và dài hạn.
  3. Nó cung cấp hiệu quả thời gian tốt bằng cách tận dụng các sự đảo ngược ngắn hạn.
  4. Cơ chế dừng lỗ tích hợp kiểm soát chặt chẽ rủi ro trên các vị trí cá nhân.
  5. Parametrization linh hoạt làm cho chiến lược này có thể áp dụng rộng rãi cho chỉ số và cổ phiếu.

Rủi ro

Mặc dù nói chung là hiệu quả, chiến lược có những hạn chế sau:

  1. Whipsaws và tín hiệu sai có thể xảy ra nếu thị trường bị giới hạn trong phạm vi. Chiến lược nên bị vô hiệu hóa trong quá trình củng cố kéo dài.
  2. Chỉ dựa vào các đường trung bình động có giới hạn độ chính xác tín hiệu.
  3. Phương pháp dừng lỗ cố định thiếu sự linh hoạt.
  4. Các thông số tối ưu cần phải được hiệu chỉnh cho các thị trường khác nhau.

Cơ hội gia tăng

Các cải tiến khác cho chiến lược này bao gồm:

  1. Kiểm tra các chiều dài trung bình động khác để tìm ra sự kết hợp tối ưu.
  2. Thêm các chỉ số hỗ trợ để tạo ra các tín hiệu đáng tin cậy hơn, ví dụ: khối lượng, số liệu biến động.
  3. Khám phá các kỹ thuật stop loss khác như trailing stop loss, stop loss dựa trên thời gian.
  4. Xây dựng khả năng thích nghi vào các quy tắc nhập cảnh và các thông số dừng lỗ cho phép điều chỉnh cho sự thay đổi của thị trường.
  5. Kết hợp các thuật toán học máy để tối ưu hóa thêm các thông số tận dụng nhiều dữ liệu lịch sử hơn.

Kết luận

Tóm lại, Chiến lược đảo ngược trung bình di chuyển kép là một cách tiếp cận rất thực tế. Nó cho phép giảm bớt pullback có lợi nhuận trong các xu hướng tăng liên tục bằng cách sử dụng phân tích trung bình di chuyển kết hợp với dừng lỗ. Nó cũng cung cấp khả năng phát hiện chế độ thị trường và kiểm soát rủi ro. Với sự cải thiện liên tục, chiến lược cung cấp tiềm năng mạnh để cung cấp hiệu suất khác biệt.


/*backtest
start: 2023-11-24 00:00:00
end: 2023-12-24 00:00:00
period: 1h
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/
// © Gold_D_Roger
//note: spreading 1 statement over multiple lines needs 1 apce + 1 tab | multi line function is 1 tab
//Recommended tickers: SPY (D), QQQ (D) and big indexes, AAPL (4H)

//@version=5
strategy("Davin's 10/200MA Pullback on SPY Strategy v2.0",
     overlay=true,
     initial_capital=10000,
     default_qty_type=strategy.percent_of_equity,
     default_qty_value=10, // 10% of equity on each trade
     commission_type=strategy.commission.cash_per_contract, 
     commission_value=0.1) //Insert your broker's rate, IB is 0.005USD or tiered

//Best parameters
// SPY D
// Stop loss 0.15
// commission of 0.005 USD using Interactive brokers
// Exit on lower close 
// Buy more when x% down --> 14%
// DO NOT include stop condition using MA crossover

// Get User Input
i_ma1           = input.int(title="MA Length 1", defval=200, step=10, group="Strategy Parameters", tooltip="Long-term MA 200")
i_ma2           = input.int(title="MA Length 2", defval=10, step=10, group="Strategy Parameters", tooltip="Short-term MA 10")
i_ma3           = input.int(title="MA Length 3", defval=50, step=1, group="Strategy Parameters", tooltip="MA for crossover signals`")
i_stopPercent   = input.float(title="Stop Loss Percent", defval=0.15, step=0.01, group="Strategy Parameters", tooltip="Hard stop loss of 10%")
i_startTime     = input(title="Start filter", defval=timestamp("01 Jan 2013 13:30 +0000"), group="Time filter", tooltip="Start date and time to begin")
i_endTime       = input(title="End filter", defval=timestamp("01 Jan 2099 19:30 +0000"), group="Time filter", tooltip="End date and time to stop")
i_lowerClose    = input.bool(title="Exit on lower close", defval=true, group="Strategy Parameters", tooltip="Wait for lower close after above 10SMA before exiting") // optimise exit strat, boolean type creates tickbox type inputs
i_contrarianBuyTheDip = input.bool(title="Buy whenever more than x% drawdown", defval=true, group="Strategy Parameters", tooltip="Buy the dip! Whenever x% or more drawdown on SPY")
i_contrarianTrigger = input.int(title="Trigger % drop to buy the dip", defval=14, step=1, group="Strategy Parameters", tooltip="% drop to trigger contrarian Buy the Dip!") 
//14% to be best for SPY 1D
//20% best for AMZN 1D
i_stopByCrossover_MA2_3 = input.bool(title="Include stop condition using MA crossover", defval=false, group="Strategy Parameters", tooltip="Sell when crossover of MA2/1 happens")

// Get indicator values
ma1 = ta.sma(close,i_ma1) //param 1
ma2 = ta.sma(close,i_ma2) //param 2
ma3 = ta.sma(close,i_ma3) //param 3
ma_9 = ta.ema(close,9) //param 2
ma_20 = ta.ema(close,20) //param 3

// Check filter(s)
f_dateFilter = true //make sure date entries are within acceptable range

// Highest price of the prev 52 days: https://www.tradingcode.net/tradingview/largest-maximum-value/#:~:text=()%20versus%20ta.-,highest(),max()%20and%20ta.
highest52 = ta.highest(high,52)
overall_change = ((highest52 - close[0]) / highest52) * 100

// Check buy/sell conditions
var float buyPrice = 0 //intialise buyPrice, this will change when we enter a trade ; float = decimal number data type 0.0
buyCondition  = (close > ma1 and close < ma2 and strategy.position_size == 0 and f_dateFilter) or (strategy.position_size == 0 and i_contrarianBuyTheDip==true and overall_change > i_contrarianTrigger and f_dateFilter) // higher than 200sma, lower than short term ma (pullback) + avoid pyramiding positions
sellCondition = close > ma2 and strategy.position_size > 0 and (not i_lowerClose or close < low[1])  //check if we already in trade + close above 10MA; 
// third condition: EITHER i_lowerClose not turned on OR closing price has to be < previous candle's LOW [1]

stopDistance  = strategy.position_size > 0 ? ((buyPrice - close)/close) : na // check if in trade > calc % drop dist from entry, if not na
stopPrice     = strategy.position_size > 0 ? (buyPrice - (buyPrice * i_stopPercent)) : na // calc SL price if in trade, if not, na
stopCondition = (strategy.position_size > 0 and stopDistance > i_stopPercent) or (strategy.position_size > 0 and (i_stopByCrossover_MA2_3==true and ma3 < ma1))


// Enter positions
if buyCondition 
    strategy.entry(id="Long", direction=strategy.long) //long only

    
if buyCondition[1] // if buyCondition is true prev candle
    buyPrice := open // entry price = current bar opening price

// Exit position
if sellCondition or stopCondition 
    strategy.close(id="Long", comment = "Exit" + (stopCondition ? "Stop loss=true" : "")) // if condition? "Value for true" : "value for false"
    buyPrice := na //reset buyPrice

// Plot
plot(buyPrice, color=color.lime, style=plot.style_linebr)
plot(stopPrice, color=color.red, style=plot.style_linebr, offset = -1)
plot(ma1, color=color.blue) //defval=200
plot(ma2, color=color.white) //defval=10
plot(ma3, color=color.yellow) // defval=50






Thêm nữa