
Chiến lược này là một hệ thống theo dõi xu hướng dựa trên khối lượng giao dịch và biến động giá để dự đoán xu hướng thị trường bằng cách tính toán chỉ số biến động khối lượng giao dịch ròng (NVO). Chiến lược kết hợp nhiều loại trung bình di chuyển (EMA, WMA, SMA, HMA) để đánh giá xu hướng thị trường bằng cách so sánh các chỉ số biến động với mối quan hệ vị trí của đường chồng lên EMA của nó và giao dịch vào thời điểm thích hợp.
Trọng tâm của chiến lược là đánh giá tâm trạng thị trường bằng cách tính toán giá trị biến động khối lượng giao dịch ròng hàng ngày. Các bước tính toán cụ thể như sau:
Các tín hiệu giao dịch được tạo ra dựa trên các quy tắc sau:
Đề xuất kiểm soát rủi ro:
Các cơ chế xác nhận tín hiệu được tối ưu hóa:
Tối ưu hóa quản lý rủi ro:
Tối ưu hóa tham số:
Chiến lược này xây dựng một hệ thống giao dịch theo dõi xu hướng hoàn chỉnh hơn bằng cách phân tích tích hợp khối lượng giao dịch và dữ liệu giá. Đặc điểm chính của chiến lược là kết hợp nhiều chỉ số kỹ thuật và cung cấp các tùy chọn cấu hình tham số linh hoạt. Mặc dù có một số rủi ro, nhưng thông qua kiểm soát rủi ro hợp lý và tối ưu hóa liên tục, chiến lược này có thể đạt được lợi nhuận ổn định trong giao dịch thực tế.
/*backtest
start: 2024-02-25 00:00:00
end: 2025-02-22 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Binance","currency":"SOL_USDT"}]
*/
//@version=5
strategy("EMA-Based Net Volume Oscillator with Trend Change", shorttitle="NVO Trend Change", overlay=false, initial_capital=100000, default_qty_type=strategy.percent_of_equity, default_qty_value=100)
// Input parameters
maType = input.string("WMA", "Moving Average Type", options=["WMA", "EMA", "SMA", "HMA"])
maLength = input.int(21, "MA Length", minval=1)
emaOverlayLength = input.int(9, "EMA Overlay Length", minval=1)
oscillatorMultiplier = input.float(1.0, "Oscillator Multiplier", minval=0.1, step=0.1)
showHistogram = input.bool(true, "Show Histogram")
stopLossPerc = input.float(1.0, "Stop Loss (%)", tooltip="Set 999 to disable")
takeProfitPerc = input.float(2.0, "Take Profit (%)", tooltip="Set 999 to disable")
// Calculate Net Volume Oscillator
priceRange = high - low
multiplier = priceRange > 0 ? (close - low) / priceRange : 0.5
var float effectiveUpVol = 0.0
var float effectiveDownVol = 0.0
if close > close[1]
effectiveUpVol := volume * multiplier
effectiveDownVol := volume * (1 - multiplier)
else if close < close[1]
effectiveUpVol := volume * multiplier
effectiveDownVol := volume * (1 - multiplier)
else
effectiveUpVol := 0.0
effectiveDownVol := 0.0
netVolume = effectiveUpVol - effectiveDownVol
dailyNetOscillator = volume > 0 ? (netVolume / volume) * 100 : 0
// Apply selected Moving Average
var float oscillator = na
if maType == "WMA"
oscillator := ta.wma(dailyNetOscillator, maLength) * oscillatorMultiplier
else if maType == "EMA"
oscillator := ta.ema(dailyNetOscillator, maLength) * oscillatorMultiplier
else if maType == "SMA"
oscillator := ta.sma(dailyNetOscillator, maLength) * oscillatorMultiplier
else if maType == "HMA"
oscillator := ta.hma(dailyNetOscillator, maLength) * oscillatorMultiplier
// EMA Overlay
emaOverlay = ta.ema(oscillator, emaOverlayLength)
// Rate of Change (ROC) for Oscillator
roc = ta.roc(oscillator, 1) // 1-period rate of change
// Trading logic
longCondition = oscillator > emaOverlay
shortCondition = oscillator < emaOverlay
// Exit conditions
exitLong = oscillator < emaOverlay and strategy.position_size > 0
exitShort = oscillator > emaOverlay and strategy.position_size < 0
// Execute trades
if longCondition and strategy.position_size <= 0
strategy.entry("Long", strategy.long)
if exitLong
strategy.close("Long")
if shortCondition and strategy.position_size >= 0
strategy.entry("Short", strategy.short)
if exitShort
strategy.close("Short")
// Stop Loss and Take Profit
stopLossLong = stopLossPerc != 999 ? strategy.position_avg_price * (1 - stopLossPerc/100) : na
takeProfitLong = takeProfitPerc != 999 ? strategy.position_avg_price * (1 + takeProfitPerc/100) : na
stopLossShort = stopLossPerc != 999 ? strategy.position_avg_price * (1 + stopLossPerc/100) : na
takeProfitShort = takeProfitPerc != 999 ? strategy.position_avg_price * (1 - takeProfitPerc/100) : na
if (not na(stopLossLong) and not na(takeProfitLong) and strategy.position_size > 0)
strategy.exit("Long SL/TP", "Long", stop=stopLossLong, limit=takeProfitLong)
if (not na(stopLossShort) and not na(takeProfitShort) and strategy.position_size < 0)
strategy.exit("Short SL/TP", "Short", stop=stopLossShort, limit=takeProfitShort)
// Plotting
plot(oscillator, "Net Volume Oscillator", color.blue)
plot(emaOverlay, "EMA Overlay", color.orange)
hline(0, "Zero Line", color.gray)
// Histogram with Trend Change Visualization
var color histogramColor = na
if oscillator > 0
histogramColor := roc >= 0 ? color.new(color.green, 70) : color.new(color.lime, 70) // Green for bullish, light green for weakening
else if oscillator < 0
histogramColor := roc >= 0 ? color.new(color.red, 70) : color.new(color.maroon, 70) // Red for bearish, light red for weakening
plot(showHistogram ? oscillator : na, style=plot.style_histogram, color=histogramColor, title="Histogram")