Chiến lược định lượng Bollinger Band Crossover

Tác giả:ChaoZhang, Ngày: 2023-12-27 14:28:21
Tags:

img

Tổng quan

Chiến lược này tạo ra tín hiệu mua và bán bằng cách so sánh đường chéo của đường nhanh và đường chậm của chỉ số MACD. Khi tín hiệu mua được tạo ra, nó sẽ mở một vị trí với một tỷ lệ phần trăm nhất định của vốn chủ sở hữu tài khoản. Các vị trí bổ sung sau đó sẽ được thêm vào tại các điểm khôi phục cụ thể. Khi lợi nhuận tích lũy của các vị trí đạt đến điểm lấy lợi nhuận được cấu hình, tất cả các vị trí sẽ được đóng.

Chiến lược logic

Lý thuyết cốt lõi của chiến lược này là so sánh sự chéo chéo của đường MACD nhanh và đường chậm để xác định xu hướng. MACD là sự khác biệt giữa các đường trung bình động, bằng cách tính toán sự khác biệt giữa đường trung bình động ngắn hạn và dài hạn, nó đánh giá xu hướng và động lực của thị trường. Sự chéo chéo giữa đường nhanh và đường chậm được coi là đường chéo vàng và đường chéo chết.

Khi đường nhanh vượt qua trên đường chậm, một chữ thập vàng được tạo ra, cho thấy thị trường đang có xu hướng tăng và chiến lược sẽ mở các vị trí dài. Khi đường nhanh vượt qua dưới đường chậm, một chữ thập chết được tạo ra, cho thấy xu hướng giảm, và chiến lược sẽ mở các vị trí ngắn.

Sau khi mở các vị trí, chiến lược sẽ thêm vào các vị trí dài hoặc ngắn hiện có tại các điểm khôi phục cụ thể. Điều này có thể làm tăng tiềm năng lợi nhuận thông qua nguyên tắc Martingale. Khi lợi nhuận tích lũy đạt đến điểm lợi nhuận được cấu hình, chiến lược sẽ đóng tất cả các vị trí.

Phân tích lợi thế

Chiến lược này có những lợi thế sau:

  1. Sử dụng chỉ số MACD để xác định xu hướng thị trường, đó là một chỉ số phân tích kỹ thuật cổ điển và đáng tin cậy.

  2. Phương pháp mở các vị trí theo lô, có thể kiểm soát rủi ro của một giao dịch duy nhất.

  3. Thêm vào các vị trí có thể mở rộng tiềm năng lợi nhuận thông qua nguyên tắc Martingale.

  4. Thiết lập điểm lợi nhuận để hạn chế lỗ.

Phân tích rủi ro

Chiến lược này cũng có một số rủi ro:

  1. Chỉ số MACD không thể dự đoán hoàn hảo các chuyển động của thị trường, có thể xảy ra các tín hiệu sai.

  2. Có nguy cơ rằng retrace sẽ mở rộng với toàn bộ vị trí thêm có thể điều chỉnh thích hợp tỷ lệ phần trăm của mỗi vị trí thêm.

  3. Thiết lập điểm lợi nhuận quá nhỏ có thể hạn chế tiềm năng lợi nhuận.

  4. Cần thiết phải cấu hình tỷ lệ phần trăm vốn hợp lý để mở các vị trí cho mỗi sản phẩm để tránh vượt quá giới hạn tài khoản.

Hướng dẫn tối ưu hóa

Chiến lược này có thể được tối ưu hóa trong các khía cạnh sau:

  1. Kiểm tra các thông số MACD, tìm các thông số phù hợp hơn cho các sản phẩm giao dịch cụ thể.

  2. Tối ưu hóa tỷ lệ phần trăm tiền và tỷ lệ phần trăm tái định hướng cho mỗi vị trí được thêm vào, tìm kết hợp tham số tối ưu.

  3. Kiểm tra các điểm lợi nhuận dài hạn và ngắn hạn để xác định mức tối ưu.

  4. Đánh giá khả năng ký quỹ của tài khoản, đặt giới hạn vị trí tối đa hợp lý cho mỗi sản phẩm.

  5. Thêm logic stop loss. Stop loss có thể kiểm soát hiệu quả lỗ khi thay đổi thị trường mạnh mẽ xảy ra.

Tóm lại

Tóm lại, đây là một chiến lược theo xu hướng điển hình. Nó sử dụng chỉ số MACD để xác định hướng xu hướng thị trường, tiếp cận thêm các vị trí trong các lô để theo xu hướng và kiếm lợi nhuận khi lợi nhuận tích lũy đạt đến một mức độ nhất định. Chiến lược đơn giản và thực tế này dễ thực hiện và phù hợp với người mới bắt đầu giao dịch định lượng. Bằng cách tối ưu hóa các tham số và mở rộng logic kiểm soát rủi ro, chiến lược có thể trở nên mạnh mẽ hơn.


/*backtest
start: 2023-11-26 00:00:00
end: 2023-12-26 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/
// © TradingSoft_tech

//@version=5
strategy("MAPM-V1", overlay=true, default_qty_value=10, max_bars_back=5000,default_qty_type = strategy.percent_of_equity, commission_value=0.1, initial_capital = 100, pyramiding=6, currency=currency.USD)

///////// Options
SignalFast = input.int(300, step=10)
SignalSlow = input.int(600, step=10)
StepAddPurchases = input.float(2.5, step=0.1)
VolumePurchases = input.int(6,step=1)
Buy = input(true)
Sell = input(true)
longProfitPerc = input.float(title="Long Take Profit (%)", minval=0.0, step=0.1, defval=1) * 0.01
shortProfitPerc = input.float(title="Short Take Profit (%)", minval=0.0, step=0.1, defval=1) * 0.01
Martingale = input.float(1.6, minval = 1, step = 0.1)
VolumeDepo = input.int(100, step=1)
PercentOfDepo = input.float(10, step=1)
Close = (close)
EnterVolume = VolumeDepo*PercentOfDepo*0.01/Close

///////// Calculation indicator
fastAverage = ta.ema(close, 8)
slowAverage = ta.ema(close, 49)
macd = fastAverage - slowAverage
macdSignalF = ta.ema(macd,SignalFast)
macdSignalS = ta.ema(macd,SignalSlow)

// Test Start
startYear = input(2005, "Test Start Year")
startMonth = input(1, "Test Start Month")
startDay = input(1, "Test Start Day")
startTest = timestamp(startYear,startMonth,startDay,0,0)

//Test End
endYear = input(2050, "Test End Year")
endMonth = input(12, "Test End Month")
endDay = input(30, "Test End Day")
endTest = timestamp(endYear,endMonth,endDay,23,59)

timeRange = time > startTest and time < endTest ? true : false

///////// Plot Data
//plot(macd, style = plot.style_histogram)
//plot(macdSignalF*10000, style = plot.style_line, color=color.red)
//plot(macdSignalS*10000, style = plot.style_line, color=color.blue)
//plot(fastAverage, style = plot.style_line, color=color.red)
//plot(slowAverage, style = plot.style_line, color=color.blue)

///////// Calculation of the updated value
var x = 0.0
if strategy.opentrades>strategy.opentrades[1]
    x := x + 1
else if strategy.opentrades==0
    x := 0
y = x+1

///////// Calculation of reference price data
entryPrice = strategy.opentrades==0? 0 : strategy.opentrades.entry_price(0)
limitLong = strategy.position_avg_price * (1 + longProfitPerc)
limitShort = strategy.position_avg_price * (1 - shortProfitPerc)
SteplimitLong = entryPrice[0]*(1-StepAddPurchases*y/100)
SteplimitShort = entryPrice[0]*(1+StepAddPurchases*y/100)

///////// Conditions for a long
bool EntryLong = ta.crossover(macdSignalF, macdSignalS) and Buy and strategy.opentrades==0 and strategy.position_size==0
bool PurchasesLong = Buy and strategy.opentrades==x and strategy.position_size>0 and x<=VolumePurchases
bool CancelPurchasesLong = strategy.position_size==0 and strategy.opentrades==0
bool TPLong = strategy.position_size>0 and strategy.opentrades!=0
///////// Entry Long + add.purchases + cancel purchases + Take profit Long
switch 
    EntryLong => strategy.entry("Entry Long", strategy.long, qty = EnterVolume)
    PurchasesLong => strategy.entry("PurchasesLong", strategy.long, qty = EnterVolume*math.pow(Martingale,y), limit = SteplimitLong)
    CancelPurchasesLong => strategy.cancel("PurchasesLong")
switch
    TPLong => strategy.exit("TPLong", qty_percent = 100, limit = limitLong)

///////// Conditions for a Short
bool EntryShort = ta.crossunder(macdSignalF, macdSignalS) and Sell and strategy.opentrades==0 and strategy.position_size==0
bool PurchasesShort = Sell and strategy.opentrades==x and strategy.position_size<0 and x<=VolumePurchases
bool CancelPurchasesShort = strategy.position_size==0 and strategy.opentrades==0
bool TPShort = strategy.position_size<0 and strategy.opentrades!=0

///////// Entry Short + add.purchases + cancel purchases + Take profit Short
switch
    EntryShort => strategy.entry("Entry Short", strategy.short, qty = EnterVolume)
    PurchasesShort => strategy.entry("PurchasesShort", strategy.short, qty = EnterVolume*math.pow(Martingale,y), limit = SteplimitShort)
    CancelPurchasesShort => strategy.cancel("PurchasesShort")
switch
    TPShort => strategy.exit("TPShort", qty_percent = 100, limit = limitShort)
    
/////////Calculation of conditions and reference data for level drawing
InTradeLong = strategy.position_size<0
InTradeShort = strategy.position_size>0
PickInLong = strategy.opentrades.entry_price(0)*(1-StepAddPurchases*y/100)
PickInShort = strategy.opentrades.entry_price(0)*(1+StepAddPurchases*y/100)

/////////Displaying the level of Take Profit
plot(InTradeLong ? na : limitLong, color=color.new(#00d146, 0), style=plot.style_linebr, linewidth=1)
plot(InTradeShort ? na : limitShort, color=color.new(#00d146, 0), style=plot.style_linebr, linewidth=1)

/////////Displaying the level of add.purchases
plot(InTradeLong ? na : PickInLong, color=color.white, style=plot.style_linebr, linewidth=1)
plot(InTradeShort ? na : PickInShort, color=color.white, style=plot.style_linebr, linewidth=1)

Thêm nữa