
Chiến lược này sử dụng hai chỉ số dao động ngẫu nhiên được đặt thành các tham số khác nhau để tạo ra và xác nhận tín hiệu giao dịch trên khung thời gian 15 giây. Lịch lý chính là để xác định điểm vào tiềm năng thông qua sự giao thoa của % K và % D của chỉ số ngẫu nhiên chính, trong khi tham khảo các chỉ số ngẫu nhiên phụ % D giá trị làm bộ lọc trạng thái thị trường, kết hợp đường trung bình di chuyển và các điều kiện lọc thời gian thị trường, xây dựng một hệ thống giao dịch với cơ chế xác nhận nhiều tầng. Chiến lược này bao gồm các tính năng nhận dạng mô hình cao thấp, bắt giữ thị trường bò và thị trường gấu tiếp tục hình dạng, và cũng có thể đặt nhiều tham số kiểm soát rủi ro để giảm tín hiệu giả.
Chiến lược sử dụng hệ thống chỉ số động đất ngẫu nhiên kép, được gọi là chỉ số chính và chỉ số tham chiếu:
Cài đặt chỉ số động đất ngẫu nhiên chính:
Tham khảo các thiết lập chỉ số động đất ngẫu nhiên:
Logic nhập được thiết kế tinh tế, xác nhận hiệu quả tín hiệu nhiều cấp:
Điều kiện nhập học:
Điều kiện nhập cảnh:
Logic Exit dựa trên sự kết hợp giữa thời gian và các tín hiệu kỹ thuật:
Chính sách này cũng tích hợp các tính năng nhận dạng hình dạng:
Cơ chế xác nhận đa tầng: Xác nhận lẫn nhau thông qua hai chỉ số rung ngẫu nhiên có cấu hình khác nhau, giảm tín hiệu giả do chỉ số đơn lẻ tạo ra, tăng độ tin cậy tín hiệu.
Quy tắc nhập cảnh và xuất cảnh chính xácChiến lược xác định rõ ràng các điều kiện nhập cảnh và thoát ra, loại bỏ chủ quan trong quyết định giao dịch, và hoàn toàn hệ thống hóa giao dịch.
Khả năng nhận dạng hình dạngMột trong những tính năng của nó là khả năng nhận biết các hình thức “thấp cao hơn” và “thấp cao hơn” trong thị trường, và nắm bắt cơ hội tiếp tục xu hướng, một chức năng mà nhiều chiến lược đơn giản không thể thực hiện được.
Bộ lọc thời gianGiảm điểm trượt và chi phí bằng cách hạn chế thời gian giao dịch trong thời gian thị trường thông thường, tránh các thời điểm có biến động cao và ít thanh khoản trước khi mở và đóng cửa.
Bộ lọc trung bình di chuyểnChức năng lọc trung bình di chuyển tùy chọn bổ sung lớp xác nhận xu hướng, đảm bảo hướng giao dịch phù hợp với xu hướng tổng thể.
Phân biệt giá cả và thông số dung lượngChiến lược đã giới thiệu nhiều tham số để kiểm soát mức độ biến động giá và phạm vi chênh lệch của chỉ số, lọc hiệu quả các tín hiệu tiếng ồn do sự biến động nhỏ.
Chuyển đổi logic động: Hệ thống có thể điều chỉnh động từ đa đầu đến đầu không và từ đầu không sang đa đầu dựa trên tình trạng thị trường, thích ứng tốt hơn.
Hệ thống cảnh báo toàn diệnChiến lược này tích hợp các điều kiện cảnh báo phong phú, giúp giám sát và thực hiện giao dịch trong thời gian thực.
Rủi ro giao dịch tần số cao trong khung thời gian ngắnChiến lược sử dụng khung thời gian 15 giây có thể tạo ra quá nhiều tín hiệu, dẫn đến giao dịch thường xuyên, tăng chi phí giao dịch và có thể tạo ra rất nhiều tín hiệu giả trong trường hợp thị trường biến động lớn.
Thiếu cơ chế ngăn chặn thiệt hại: Không có thực hiện dừng lỗ rõ ràng trong mã, có thể có nguy cơ mất mát lớn nếu xu hướng đột ngột đảo ngược. Thiếu kiểm soát rủi ro là một trong những điểm yếu chính của chiến lược.
Độ nhạy tham sốMột số tham số chính xác được sử dụng trong chiến lược (ví dụ như ngưỡng chênh lệch 0,15 hoặc giới hạn chênh lệch 0,1%) có thể quá nhạy cảm với các điều kiện thị trường khác nhau và cần phải được điều chỉnh thường xuyên.
Chi phí cơ hội của giới hạn thời gianChỉ giao dịch trong thời gian thị trường thông thường có thể bỏ lỡ một số cơ hội quan trọng trước và sau thị trường, đặc biệt là phản ứng của thị trường sau các thông báo lớn.
Sự phụ thuộc vào tính thanh khoảnChiến lược tần số cao có thể gặp vấn đề trượt điểm trong thị trường ít lưu động, giá thực hiện có thể khác biệt đáng kể so với giá khi tín hiệu được tạo ra.
Chỉ số kỹ thuật chậm trễCác chỉ số biến động ngẫu nhiên tự nó có một sự chậm trễ, đặc biệt là trong thị trường biến động nhanh, có thể không thể bắt kịp các bước ngoặt.
Rủi ro quá phù hợp: Điều chỉnh chính xác các tham số chiến lược có thể dẫn đến quá phù hợp với dữ liệu lịch sử và không hoạt động tốt trong môi trường thị trường tương lai.
Tăng hệ thống chống thiệt hạiĐiểm tối ưu hóa quan trọng nhất là thực hiện hệ thống dừng lỗ thông minh, có thể xem xét chiến lược dừng lỗ dựa trên ATR, hoặc sử dụng mức độ kỹ thuật (như điểm cao và thấp trong giai đoạn trước) làm điểm dừng lỗ để hạn chế tổn thất tối đa cho một giao dịch.
Tiếp tục quản lý vị trí: Định lượng giao dịch được điều chỉnh động dựa trên biến động thị trường và khả năng chịu rủi ro của tài khoản, sử dụng cấu hình vị trí khác nhau với cường độ tín hiệu khác nhau để tối ưu hóa tỷ lệ sử dụng vốn và tỷ lệ lợi nhuận rủi ro.
Thêm xác nhận số lượng giao dịch: Để tích hợp các chỉ số giao dịch vào hệ thống, yêu cầu các tín hiệu đầu vào quan trọng phải có đủ hỗ trợ giao dịch, có thể lọc các tín hiệu không đáng tin cậy trong môi trường giao dịch thấp.
Tích hợp đa chỉ sốCân nhắc kết hợp với các chỉ số động lực và xu hướng khác như RSI, MACD hoặc Blink, để xây dựng quan điểm thị trường toàn diện hơn và tăng cường sự ổn định của hệ thống.
Tối ưu hóa khung thời gian: Kiểm tra các khung thời gian cơ bản khác nhau, chẳng hạn như 1 phút hoặc 5 phút, có thể làm giảm tiếng ồn trong khi vẫn có đủ cơ hội giao dịch, tìm ra điểm cân bằng tốt nhất giữa chất lượng và số lượng tín hiệu.
Thêm theo dõi thống kê phản hồi- Đạt được các chỉ số hiệu suất phản hồi toàn diện hơn, chẳng hạn như rút tối đa, tỷ lệ Sharpe, tỷ lệ thắng, tỷ lệ thua lỗ, để đánh giá hiệu suất chiến lược một cách khoa học hơn.
Các tham số thích ứng: Chuyển đổi các tham số cố định thành tham số thích ứng dựa trên sự thay đổi động của thị trường, cho phép chiến lược thích ứng với các môi trường thị trường khác nhau.
Thêm lọc môi trường thị trườngThêm VIX (thực tế biến động) hoặc các chỉ số tương tự làm điều kiện lọc môi trường thị trường, điều chỉnh các tham số chiến lược hoặc tạm ngưng giao dịch trong môi trường biến động cao.
Chiến lược giao dịch arbitrage là một hệ thống giao dịch tần số cao ngắn hạn được thiết kế cẩn thận, tăng độ tin cậy của tín hiệu giao dịch thông qua các cơ chế xác nhận nhiều lớp như chỉ số dao động ngẫu nhiên kép, lọc trung bình di chuyển và lọc thời gian. Chiến lược này xác định các điểm chuyển đổi bán tháo và xu hướng tiếp tục ngắn hạn trong thời gian thị trường thông thường, phù hợp với thị trường có đủ tính linh hoạt và biến động vừa phải.
Mặc dù cấu trúc thiết kế chiến lược được hoàn thiện, nhưng vẫn còn thiếu các cơ chế quản lý rủi ro quan trọng như rủi ro vốn có của giao dịch tần số cao và thiếu dừng lỗ. Để nâng cao tính ổn định và lợi nhuận lâu dài của chiến lược, khuyến nghị thêm các biện pháp tối ưu hóa như cơ chế dừng lỗ, hệ thống quản lý vị trí, xác nhận khối lượng giao dịch và kết hợp nhiều chỉ số. Ngoài ra, chuyển đổi các tham số cố định thành tham số thích ứng và tăng theo dõi thống kê phản hồi toàn diện sẽ giúp chiến lược duy trì hiệu suất ổn định trong các môi trường thị trường khác nhau.
Với sự hiểu biết sâu sắc và tối ưu hóa liên tục của các nhà giao dịch về chiến lược này, hệ thống giao dịch này có tiềm năng trở thành một phần hiệu quả trong bộ công cụ giao dịch trong ngày, đặc biệt phù hợp cho các nhà giao dịch có hiểu biết sâu sắc về các chỉ số kỹ thuật và có thể giám sát thị trường kịp thời.
/*backtest
start: 2025-01-01 00:00:00
end: 2025-06-17 00:00:00
period: 4h
basePeriod: 4h
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
*/
//@version=6
strategy("Dual TF Stochastic Strategy", overlay=false)
// Input parameters with updated defaults
primaryLen = input.int(12, "Primary Stoch K Length", minval=1) // Changed from 14 to 12
primarySmooth = input.int(12, "Primary Stoch K Smoothing", minval=1) // Changed from 3 to 12
primaryDLen = input.int(12, "Primary Stoch D Length", minval=1) // Changed from 3 to 12
primaryRes = input.timeframe("15S", "Primary Timeframe") // Changed from "" to "15S"
refLen = input.int(12, "Reference Stoch K Length", minval=1) // Changed from 14 to 12
refSmooth = input.int(15, "Reference Stoch K Smoothing", minval=1) // Changed from 3 to 15
refDLen = input.int(30, "Reference Stoch D Length", minval=1) // Changed from 3 to 30
refRes = input.timeframe("15S", "Reference Timeframe") // Changed from "D" to "15S"
tolerance = input.float(0.1, "Ref D Tolerance %", minval=0.1, maxval=10.0, step=0.1) // Changed from 1.0 to 0.1
maxPriceDiff = input.float(0.1, "Maximum Price % Difference", minval=0.1, maxval=5.0, step=0.1) // Changed from 1.0 to 0.1
closeKThreshold = input.float(0.7, "Close %K Tolerance %", minval=0.1, maxval=10.0, step=0.1) // Changed from 5.0 to 0.7
minPriceDiffShort = input.float(0.1, "Min Price % Diff for Close %K Short", minval=0.1, maxval=5.0, step=0.1) // Changed from 0.5 to 0.1
showLabels = input.bool(true, "Show Crossover/Crossunder Labels")
// Time Filters (America/New_York timezone, UTC-4)
is_premarket = hour(time, "America/New_York") < 9
is_postmarket = hour(time, "America/New_York") >= 16
is_regular_hours = hour(time, "America/New_York") >= 9 and hour(time, "America/New_York") < 16
is_exit_time = hour(time, "America/New_York") >= 15 and minute(time, "America/New_York") >= 30 // 3:30 PM ET
// Moving Average Settings
useMAFilter = input.bool(true, "Use Moving Average Filter")
maLength = input.int(200, "Moving Average Length", minval=1)
maType = input.string("SMA", "Moving Average Type", options=["SMA", "EMA", "WMA", "VWMA"])
maTimeframe = input.timeframe("", "Moving Average Timeframe")
// Stochastic Calculations
primaryHighest = ta.highest(high, primaryLen)
primaryLowest = ta.lowest(low, primaryLen)
primaryK_raw = 100 * (close - primaryLowest) / (primaryHighest - primaryLowest)
primaryK = ta.sma(primaryK_raw, primarySmooth)
primaryD = ta.sma(primaryK, primaryDLen)
[primaryK_tf, primaryD_tf] = request.security(syminfo.tickerid, primaryRes, [primaryK, primaryD])
refHighest = ta.highest(high, refLen)
refLowest = ta.lowest(low, refLen)
refK_raw = 100 * (close - refLowest) / (refHighest - refLowest)
refK = ta.sma(refK_raw, refSmooth)
refD = ta.sma(refK, refDLen)
[refK_tf, refD_tf] = request.security(syminfo.tickerid, refRes, [refK, refD])
// Calculate Moving Average
var float ma = na
if useMAFilter
if maType == "SMA"
ma := request.security(syminfo.tickerid, maTimeframe, ta.sma(close, maLength))
else if maType == "EMA"
ma := request.security(syminfo.tickerid, maTimeframe, ta.ema(close, maLength))
else if maType == "WMA"
ma := request.security(syminfo.tickerid, maTimeframe, ta.wma(close, maLength))
else if maType == "VWMA"
ma := request.security(syminfo.tickerid, maTimeframe, ta.vwma(close, maLength))
// Price relative to MA
priceAboveMA = not useMAFilter or close > ma
priceBelowMA = not useMAFilter or close < ma
// Crossover Detection and Tracking
crossOver = ta.crossover(primaryK_tf, primaryD_tf)
crossUnder = ta.crossunder(primaryK_tf, primaryD_tf)
// Separate tracking for crossover and crossunder %K and price
var float lastCrossOverK = na
var float lastCrossOverPrice = na
var float currentCrossOverK = na
var float currentCrossOverPrice = na
var float lastCrossUnderK = na
var float lastCrossUnderPrice = na
var float currentCrossUnderK = na
var float currentCrossUnderPrice = na
// Update crossover tracking variables
if crossOver
lastCrossOverK := nz(currentCrossOverK, primaryK_tf[1])
lastCrossOverPrice := nz(currentCrossOverPrice, close[1])
currentCrossOverK := primaryK_tf
currentCrossOverPrice := close
// Update crossunder tracking variables
if crossUnder
lastCrossUnderK := nz(currentCrossUnderK, primaryK_tf[1])
lastCrossUnderPrice := nz(currentCrossUnderPrice, close[1])
currentCrossUnderK := primaryK_tf
currentCrossUnderPrice := close
// Calculate differences separately
crossOverPriceDiffPercent = math.abs((currentCrossOverPrice - lastCrossOverPrice) / lastCrossOverPrice * 100)
crossOverKDiffPercent = math.abs((currentCrossOverK - lastCrossOverK) / lastCrossOverK * 100)
crossUnderPriceDiffPercent = math.abs((currentCrossUnderPrice - lastCrossUnderPrice) / lastCrossUnderPrice * 100)
crossUnderKDiffPercent = math.abs((currentCrossUnderK - lastCrossUnderK) / lastCrossUnderK * 100)
isKCloseCrossUnder = crossUnderKDiffPercent <= closeKThreshold and not na(lastCrossUnderK)
// New condition for long entry based on %K and refD_tf difference
kAndRefDDiffClose = crossOver and math.abs(currentCrossOverK - refD_tf) <= 0.15
// Labels for crossover and crossunder (optional)
if showLabels
if crossOver
diffKandRefD = math.abs(currentCrossOverK - refD_tf)
label.new(bar_index, 50, "CrossOver\nDiff K-RefD: " + str.tostring(diffKandRefD, "#.###"), color=color.green, textcolor=color.black, style=label.style_label_up)
if crossUnder
diffKandRefD = math.abs(currentCrossUnderK - refD_tf)
label.new(bar_index, 50, "CrossUnder\nDiff K-RefD: " + str.tostring(diffKandRefD, "#.###"), color=color.red, textcolor=color.black, style=label.style_label_down)
// Entry Conditions
longKCondition = crossOver and (na(lastCrossOverK) or currentCrossOverK > lastCrossOverK)
shortKCondition = crossUnder and (crossUnderPriceDiffPercent <= maxPriceDiff)
closeKShortCondition = crossUnder and isKCloseCrossUnder and (crossUnderPriceDiffPercent > minPriceDiffShort)
crossUnderBetween50and45 = crossUnder and currentCrossUnderK <= 50 and currentCrossUnderK > 45
// Long to Short if crossunder %K > 80 OR < 60
longToShortCondition = crossUnder and (currentCrossUnderK > 80 or currentCrossUnderK < 60) and strategy.position_size > 0 and is_regular_hours
upperLimit = refD_tf * (1 + tolerance/100)
lowerLimit = refD_tf * (1 - tolerance/100)
withinToleranceLong = primaryK_tf >= lowerLimit and primaryK_tf <= upperLimit
withinToleranceShort = primaryK_tf >= lowerLimit and primaryK_tf <= upperLimit
// Final Entry Conditions with MA filter
longCondition = ((longKCondition and (refD_tf >= 50 or refD_tf < 20)) or kAndRefDDiffClose) and is_regular_hours and not is_exit_time and priceAboveMA
shortCondition = (shortKCondition or (crossUnder and withinToleranceShort and (crossUnderPriceDiffPercent <= maxPriceDiff)) or closeKShortCondition or longToShortCondition or crossUnderBetween50and45) and is_regular_hours and not is_exit_time and priceBelowMA
// Short-to-Long Transition Condition with MA filter
shortToLongCondition = crossOver and currentCrossOverK < 25 and strategy.position_size < 0 and is_regular_hours and not is_exit_time and priceAboveMA
// Tracking for %K crossing under refD_tf
var float lastPrimaryKCrossUnderRefD = na
var float currentPrimaryKCrossUnderRefD = na
var bool isPrimaryKCrossUnderRefD = false
// Check if primary %K crosses under reference %D
isPrimaryKCrossUnderRefD := ta.crossunder(primaryK_tf, refD_tf)
// Update tracking for %K crossing under refD
if isPrimaryKCrossUnderRefD
lastPrimaryKCrossUnderRefD := currentPrimaryKCrossUnderRefD
currentPrimaryKCrossUnderRefD := primaryK_tf
// Exit Conditions
if is_exit_time
strategy.close("Long")
strategy.close("Short")
else if isPrimaryKCrossUnderRefD and not na(lastPrimaryKCrossUnderRefD) and currentPrimaryKCrossUnderRefD < lastPrimaryKCrossUnderRefD
strategy.close("Long")
else if (ta.crossunder(primaryK_tf, primaryD_tf) and primaryK_tf < refD_tf and refD_tf < 60)
strategy.close("Long")
if (ta.crossover(primaryK_tf, primaryD_tf) and primaryK_tf > refD_tf and refD_tf > 20) and not is_exit_time
strategy.close("Short")
// Track if crossunder happens above 85
var bool crossUnderAbove85 = false
// Detect crossunder above 85
if crossUnder and currentCrossUnderK > 85
crossUnderAbove85 := true
// Reset condition if %K crosses over %D
if ta.crossover(primaryK_tf, primaryD_tf)
crossUnderAbove85 := false
// Track previous crossover/crossunder values for Higher Low/Lower High detection
var float prevCrossOverK = na
var float prevCrossUnderK = na
// Update previous values on new crossovers/crossunders
if crossOver
prevCrossOverK := currentCrossOverK
if crossUnder
prevCrossUnderK := currentCrossUnderK
// Higher Low and Lower High conditions
higherLowCondition = crossOver and not na(prevCrossOverK) and currentCrossOverK > prevCrossOverK
lowerHighCondition = crossUnder and not na(prevCrossUnderK) and currentCrossUnderK < prevCrossUnderK
// Strategy Entries and Transitions
if longCondition
strategy.entry("Long", strategy.long)
if shortCondition
if strategy.position_size > 0 // If in a long position, close it first
strategy.close("Long")
strategy.entry("Short", strategy.short)
if shortToLongCondition
strategy.close("Short")
if ((longKCondition and (refD_tf >= 50 or refD_tf < 20)) or kAndRefDDiffClose) // Check full longCondition minus time (already checked)
strategy.entry("Long", strategy.long)
// Add label for Short to Long Transition
if shortToLongCondition
label.new(bar_index, na, "T", color=color.green, textcolor=color.white, style=label.style_label_up)
// Add label for Long to Short Transition
if longToShortCondition
label.new(bar_index, na, "T", color=color.red, textcolor=color.white, style=label.style_label_down)
// Plotting
plot(primaryK_tf, "Primary %K", color=color.white, linewidth=1)
plot(primaryD_tf, "Primary %D", color=color.orange, linewidth=1)
plot(refK_tf, "Reference %K", color=color.navy, linewidth=1)
plot(refD_tf, "Reference %D", color=color.rgb(33, 233, 243), linewidth=2)
// Plot current and last %K only for crossUnder when isKCloseCrossUnder is true and currentCrossUnderK < lastCrossUnderK
plot(crossUnder and isKCloseCrossUnder and currentCrossUnderK < lastCrossUnderK ? currentCrossUnderK : na, "Current CrossUnder %K (Close)", color=color.green, style=plot.style_cross, linewidth=2)
plot(crossUnder and isKCloseCrossUnder and currentCrossUnderK < lastCrossUnderK ? lastCrossUnderK : na, "Last CrossUnder %K (Close)", color=color.red, style=plot.style_cross, linewidth=2)
h0 = hline(85, "Upper Band", color=color.rgb(242, 187, 21))
hline(50, "Middle Band", color=#eaff04)
h1 = hline(20, "Lower Band", color=color.rgb(242, 187, 21))
h2 = hline(40, "Lower Band", color=#787B86)
h3 = hline(60, "Lower Band", color=#787B86)
h = hline(0, "Lower Band", color=#787B86)
h5 = hline(100, "Lower Band", color=#787B86)
fill(h0, h1, color=color.rgb(33, 150, 243, 90), title="Background")
fill(h, h1, color=#1be2781d, title="Background")
fill(h0, h5, color=#e21b742d, title="Background")
// Plot the MA if enabled
plot(useMAFilter ? ma : na, "Moving Average", color=color.yellow, linewidth=2)
// Add plot for visualization (optional)
plot(isPrimaryKCrossUnderRefD ? primaryK_tf : na, "Primary %K CrossUnder RefD", color=color.purple, style=plot.style_cross, linewidth=2)
plot(isPrimaryKCrossUnderRefD and not na(lastPrimaryKCrossUnderRefD) ? lastPrimaryKCrossUnderRefD : na, "Last Primary %K CrossUnder RefD", color=color.fuchsia, style=plot.style_cross, linewidth=2)
// Add new alert conditions
alertcondition(higherLowCondition, title="Stoch Higher Low", message="Stoch Higher Low Pattern Detected")
alertcondition(lowerHighCondition, title="Stoch Lower High", message="Stoch Lower High Pattern Detected")
// Plot markers for Higher Low and Lower High patterns
plot(higherLowCondition ? currentCrossOverK : na, "Higher Low", color=color.green, style=plot.style_cross, linewidth=2)
plot(lowerHighCondition ? currentCrossUnderK : na, "Lower High", color=color.red, style=plot.style_cross, linewidth=2)
// Alert conditions
alertcondition(crossOver, title="Stochastic %K Crossed Over %D", message="Stochastic %K crossed over %D")
alertcondition(crossUnder, title="Stochastic %K Crossed Under %D", message="Stochastic %K crossed under %D")
alertcondition(crossOver and primaryK_tf > 50, title="Stochastic %K Crossed Over %D Above 50", message="Stochastic %K crossed over %D above 50")
alertcondition(crossOver and primaryK_tf > refD_tf, title="Stochastic %K Crossed Over %D Above Reference %D", message="Stochastic %K crossed over %D above Reference %D")
alertcondition(longCondition, title="Long Entry Signal", message="Long entry signal triggered")
alertcondition(shortCondition, title="Short Entry Signal", message="Short entry signal triggered")
alertcondition(shortToLongCondition, title="Short to Long Transition", message="Short to Long transition triggered")
alertcondition(longToShortCondition, title="Long to Short Transition", message="Long to Short transition triggered")
alertcondition(isPrimaryKCrossUnderRefD, title="Primary %K Crossed Under Reference %D", message="Primary %K crossed under Reference %D")
alertcondition(crossOver and primaryK_tf > refD_tf, title="Bullish Crossover Above Ref %D", message="Bull: Dual Stoch")
alertcondition(crossUnder and primaryK_tf < refD_tf, title="Bearish Crossunder Below Ref %D", message="Bear: Dual Stoch")