
Chiến lược này được phát triển dựa trên chỉ số kênh giá Donchian. Chỉ số này tạo ra kênh giá bằng cách tính toán giá cao nhất và giá thấp nhất trong một chu kỳ nhất định. Chiến lược sử dụng kênh giá để thực hiện giao dịch hai chiều và đặt giá dừng và giá dừng.
Đầu tiên, chiến lược tính toán h và l giới hạn trên của kênh giá dựa trên tham số pclen ⋅ trung tâm đường trung là giá trị trung bình của giới hạn trên và dưới của kênh giá ⋅ sau đó, dựa trên tham số dừng của vị trí dài và vị trí trống ⋅ tp, tính toán giá dừng tpl và tps ⋅ giá dừng được cố định là trung tâm của kênh giá ⋅ khi giá vượt qua kênh giá, tính toán vị trí giao dịch theo hướng khác nhau dựa trên kích thước rủi ro risklong và riskshort ⋅ chiến lược sẽ phẳng vị trí khi giá quay trở lại kênh ⋅ ngoài ra, cũng có thiết lập thời gian vượt qua, chỉ giao dịch trong khoảng thời gian được chỉ định ⋅
Các giao dịch được thực hiện theo các logic sau:
Tín hiệu mở nhiều vị trí: Giá lớn hơn giới hạn h trên kênh và mở nhiều vị trí khi quay trở lại bên trong kênh Tín hiệu bán tháo nhiều vị trí: bán tháo nhiều vị trí khi giá thấp hơn đường trung tâm (stop loss) hoặc cao hơn giá dừng (stop loss)
Tín hiệu mở kho trống: Giá thấp hơn giới hạn dưới của kênh l và quay trở lại trong kênh khi mở kho trống Tín hiệu lỗ trống: Giá cao hơn đường trung tâm (stop loss) hoặc thấp hơn giá dừng (stop price) khi lỗ trống
Chiến lược này có những ưu điểm sau:
Chiến lược này cũng có một số rủi ro:
Những rủi ro này có thể được giảm và kiểm soát bằng cách điều chỉnh các tham số và theo dõi bằng tay.
Chiến lược này cũng có thể được tối ưu hóa theo các khía cạnh sau:
Chiến lược này nói chung là một phương pháp hiệu quả để thực hiện giao dịch hai chiều bằng cách sử dụng chỉ số kênh giá. Thiết lập các mô-đun kiểm soát dừng lỗ và kiểm soát vị trí, có thể kiểm soát rủi ro tốt. Với một số tối ưu hóa và điều chỉnh, có thể trở thành một chiến lược giao dịch định lượng mạnh mẽ.
/*backtest
start: 2023-01-31 00:00:00
end: 2024-01-31 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//Noro
//2020
//@version=4
strategy(title = "Noro's RiskDonchian Strategy", shorttitle = "RiskDonchian str", overlay = true, default_qty_type = strategy.percent_of_equity, initial_capital = 100, default_qty_value = 100, commission_value = 0.1)
//Settings
needlong = input(true, defval = true, title = "Long")
needshort = input(true, defval = true, title = "Short")
tp = input(defval = 20.0, minval = 1, title = "Take-profit, %")
tptype = input(defval = "2. Fix", options = ["1. None", "2. Fix", "3. Trailing"], title = "Take-profit type")
sltype = input(defval = "2. Center", options = ["1. None", "2. Center"], title = "Take-profit type")
risklong = input(5.0, minval = 0.0, maxval = 99.9, title = "Risk size for long, %")
riskshort = input(5.0, minval = 0.0, maxval = 99.9, title = "Risk size for short, %")
pclen = input(50, minval = 1, title = "Price Channel Length")
showll = input(true, defval = true, title = "Show lines")
showbg = input(false, defval = false, title = "Show Background")
showof = input(true, defval = true, title = "Show Offset")
showlabel = input(true, defval = true, title = "Show label")
fromyear = input(1900, defval = 1900, minval = 1900, maxval = 2100, title = "From Year")
toyear = input(2100, defval = 2100, minval = 1900, maxval = 2100, title = "To Year")
frommonth = input(01, defval = 01, minval = 01, maxval = 12, title = "From Month")
tomonth = input(12, defval = 12, minval = 01, maxval = 12, title = "To Month")
fromday = input(01, defval = 01, minval = 01, maxval = 31, title = "From day")
today = input(31, defval = 31, minval = 01, maxval = 31, title = "To day")
//Price Channel
h = highest(high, pclen)
l = lowest(low, pclen)
center = (h + l) / 2
//Take-profit
tpl = 0.0
tpl := tptype == "2. Fix" and strategy.position_size > 0 ? tpl[1] : h * (100 + tp) / 100
//Stop-loss
tps = 0.0
tps := tptype == "2. Fix" and strategy.position_size < 0 ? tps[1] : l * (100 - tp) / 100
//Lines
tplcol = showll and needlong and tptype != "1. None" ? color.lime : na
pclcol = showll and needlong ? color.blue : na
sllcol = showll and needlong and sltype != "1. None" ? color.red : na
tpscol = showll and needshort and tptype != "1. None" ? color.lime : na
pcscol = showll and needshort ? color.blue : na
slscol = showll and needshort and sltype != "1. None" ? color.red : na
offset = showof ? 1 : 0
plot(tpl, offset = offset, color = tplcol, title = "TP Long")
plot(h, offset = offset, color = pclcol, title = "Channel High")
plot(center, offset = offset, color = sllcol, title = "SL Long")
plot(center, offset = offset, color = slscol, title = "SL Short")
plot(l, offset = offset, color = pcscol, title = "Channel Low")
plot(tps, offset = offset, color = tpscol, title = "TP Short")
//Background
size = strategy.position_size
bgcol = showbg == false ? na : size > 0 ? color.lime : size < 0 ? color.red : na
bgcolor(bgcol, transp = 70)
//Lot size
risksizelong = -1 * risklong
risklonga = ((center / h) - 1) * 100
coeflong = abs(risksizelong / risklonga)
lotlong = (strategy.equity / close) * coeflong
risksizeshort = -1 * riskshort
riskshorta = ((center / l) - 1) * 100
coefshort = abs(risksizeshort / riskshorta)
lotshort = (strategy.equity / close) * coefshort
//Trading
truetime = time > timestamp(fromyear, frommonth, fromday, 00, 00) and time < timestamp(toyear, tomonth, today, 23, 59)
mo = 0
mo := strategy.position_size != 0 ? 0 : high >= center[1] and low <= center[1] ? 1 : mo[1]
if h > 0
longlimit = tptype == "1. None" ? na : tpl
longstop = sltype == "1. None" ? na : center
strategy.entry("Long", strategy.long, lotlong, stop = h, when = strategy.position_size <= 0 and needlong and truetime and mo)
strategy.exit("TP Long", "Long", limit = longlimit, stop = longstop)
shortlimit = tptype == "1. None" ? na : tps
shortstop = sltype == "1. None" ? na : center
strategy.entry("Short", strategy.short, lotshort, stop = l, when = strategy.position_size >= 0 and needshort and truetime and mo)
strategy.exit("Exit Short", "Short", limit = shortlimit, stop = shortstop)
if time > timestamp(toyear, tomonth, today, 23, 59)
strategy.close_all()
strategy.cancel("Long")
strategy.cancel("Short")
if showlabel
//Drawdown
max = 0.0
max := max(strategy.equity, nz(max[1]))
dd = (strategy.equity / max - 1) * 100
min = 100.0
min := min(dd, nz(min[1]))
//Label
min := round(min * 100) / 100
labeltext = "Drawdown: " + tostring(min) + "%"
var label la = na
label.delete(la)
tc = min > -100 ? color.white : color.red
osx = timenow + round(change(time)*10)
osy = highest(100)