Chiến lược EMA Cross ADR là một chiến lược giao dịch định lượng dựa trên nền tảng TradingView. Nó kết hợp nhiều chỉ số kỹ thuật để xác định xu hướng, tín hiệu lọc và đặt mức dừng lỗ và lấy lợi nhuận. Chiến lược sử dụng hai Mức trung bình chuyển động (EMA) với các khoảng thời gian khác nhau để xác định xu hướng chính, sử dụng Mức trung bình hàng ngày (ADR) làm bộ lọc biến động, và động lập mức dừng lỗ và lấy lợi nhuận dựa trên tỷ lệ rủi ro-lợi nhuận. Ngoài ra, chiến lược kết hợp các biện pháp quản lý rủi ro như cửa sổ thời gian giao dịch, dừng phá vỡ, và giới hạn lỗ tối đa hàng ngày, nhằm mục đích nắm bắt các cơ hội xu hướng trong khi kiểm soát chặt chẽ rủi ro giảm.
Dual EMA Crossover: Chiến lược sử dụng hai EMA với các khoảng thời gian khác nhau để xác định xu hướng. Khi EMA ngắn hạn vượt qua trên EMA dài hạn, nó được coi là xu hướng tăng, tạo ra tín hiệu dài; ngược lại, khi EMA ngắn hạn vượt qua dưới EMA dài hạn, nó được coi là xu hướng giảm, tạo ra tín hiệu ngắn.
Bộ lọc biến động ADR: Để tránh tạo tín hiệu giao dịch trong môi trường biến động thấp, chiến lược giới thiệu chỉ số ADR như một bộ lọc biến động. Các vị trí chỉ được phép mở khi giá trị ADR vượt quá ngưỡng tối thiểu đã đặt trước.
Cửa sổ thời gian giao dịch: Chiến lược cho phép người dùng đặt thời gian bắt đầu và kết thúc giao dịch hàng ngày. Các giao dịch chỉ được thực hiện trong cửa sổ thời gian được chỉ định, giúp tránh các giai đoạn không thanh khoản hoặc biến động cao.
Động thái dừng lỗ và lấy lợi nhuận: Chiến lược tính toán năng động giá dừng lỗ và lấy lợi nhuận dựa trên giá trung bình cao nhất và thấp nhất của các ngọn nến N gần đây nhất, kết hợp với tỷ lệ rủi ro-lợi nhuận được đặt trước. Điều này đảm bảo rằng rủi ro-lợi nhuận của mỗi giao dịch có thể kiểm soát được.
Break-Even Stops: Khi một vị trí đạt đến một mức lợi nhuận nhất định (tỷ lệ rủi ro-lợi nhuận do người dùng xác định), chiến lược di chuyển stop-loss đến điểm break-even (giá nhập). Điều này giúp bảo vệ lợi nhuận đã kiếm được.
Giới hạn lỗ hàng ngày tối đa: Để kiểm soát mức lỗ tối đa mỗi ngày, chiến lược đặt giới hạn lỗ hàng ngày. Một khi lỗ hàng ngày đạt đến giới hạn này, chiến lược sẽ ngừng giao dịch cho đến khi mở cửa vào ngày hôm sau.
Đóng tất cả các vị trí vào cuối ngày: Bất kể các vị trí đã đạt đến mức lợi nhuận hoặc dừng lỗ, chiến lược sẽ đóng tất cả các vị trí vào một thời gian cố định mỗi ngày giao dịch (ví dụ: 16:00) để tránh rủi ro qua đêm.
Khả năng theo dõi xu hướng mạnh mẽ: Bằng cách sử dụng hai đường chéo EMA để xác định xu hướng, chiến lược có thể nắm bắt hiệu quả các xu hướng thị trường chính, do đó cải thiện tỷ lệ chiến thắng và tiềm năng lợi nhuận.
Khả năng thích nghi với biến động tốt: Việc giới thiệu chỉ số ADR như một bộ lọc biến động có thể tránh giao dịch thường xuyên trong môi trường biến động thấp, giảm tổn thất do tín hiệu không hợp lệ và đột phá sai.
Kiểm soát rủi ro nghiêm ngặt: Chiến lược đặt ra các biện pháp kiểm soát rủi ro từ nhiều khía cạnh, bao gồm dừng lỗ và lấy lợi nhuận năng động, dừng lỗ, và giới hạn lỗ hàng ngày tối đa, kiểm soát hiệu quả rủi ro giảm và cải thiện lợi nhuận điều chỉnh rủi ro.
Cài đặt tham số linh hoạt: Các tham số khác nhau của chiến lược, chẳng hạn như thời gian EMA, độ dài ADR, tỷ lệ rủi ro-lợi nhuận, cửa sổ thời gian giao dịch, v.v., có thể được thiết lập linh hoạt theo sở thích của người dùng và đặc điểm thị trường để tối ưu hóa hiệu suất chiến lược.
Mức độ tự động hóa cao: Chiến lược dựa trên nền tảng TradingView, và logic giao dịch được thực hiện hoàn toàn bởi chương trình, giảm sự can thiệp của cảm xúc con người và đánh giá chủ quan, điều này góp phần vào hoạt động ổn định lâu dài của chiến lược.
Rủi ro tối ưu hóa tham số: Mặc dù các tham số của chiến lược có thể được điều chỉnh linh hoạt, nhưng tối ưu hóa quá mức có thể dẫn đến quá phù hợp và hiệu suất kém ngoài mẫu.
Rủi ro sự kiện đột ngột: Chiến lược chủ yếu giao dịch dựa trên các chỉ số kỹ thuật và có thể không phản ứng đầy đủ với một số sự kiện cơ bản đột ngột lớn, chẳng hạn như thay đổi chính sách hoặc biến động dữ liệu kinh tế đáng kể, dẫn đến rút tiền lớn.
Rủi ro đảo ngược xu hướng: Trong những giai đoạn quan trọng của sự đảo ngược xu hướng, các tín hiệu chéo EMA kép có thể bị trì hoãn, khiến chiến lược không có thời điểm tốt nhất để thiết lập các vị trí hoặc chịu tổn thất khi bắt đầu đảo ngược xu hướng.
Rủi ro thanh khoản: Mặc dù chiến lược đặt ra một cửa sổ thời gian giao dịch, nếu thanh khoản của các công cụ giao dịch kém, nó vẫn có thể phải đối mặt với các rủi ro như trượt và trì hoãn giao dịch, ảnh hưởng đến hiệu suất chiến lược.
Rủi ro thất bại chỉ số kỹ thuật: Chiến lược phụ thuộc rất nhiều vào các chỉ số kỹ thuật. Nếu điều kiện thị trường thay đổi đáng kể, khiến các chỉ số mất ý nghĩa ban đầu, hiệu quả của chiến lược có thể giảm.
Giới thiệu các chỉ số có nhiều chiều: Trên cơ sở các EMA và ADR kép hiện có, xem xét việc giới thiệu các chỉ số kỹ thuật hiệu quả hơn, chẳng hạn như MACD và RSI, để cải thiện độ tin cậy và độ bền của tín hiệu.
Tối ưu hóa tham số động: Thiết lập một cơ chế tối ưu hóa tham số điều chỉnh động các tham số chiến lược chính dựa trên các trạng thái thị trường khác nhau (như xu hướng hoặc dao động) để thích nghi với những thay đổi của thị trường.
Bao gồm các yếu tố cơ bản: Xem xét một số chỉ số cơ bản quan trọng, chẳng hạn như dữ liệu kinh tế và hướng chính sách, có thể giúp chiến lược nắm bắt tốt hơn xu hướng thị trường và tránh rủi ro hệ thống kịp thời.
Cải thiện các cơ chế dừng lỗ và lấy lợi nhuận: Tăng cường tối ưu hóa logic dừng lỗ và lấy lợi nhuận dựa trên cơ sở dừng lỗ và lấy lợi nhuận năng động hiện có, chẳng hạn như giới thiệu dừng lại và lấy lợi nhuận một phần, để bảo vệ lợi nhuận và kiểm soát rủi ro tốt hơn.
Nhiều công cụ và khung thời gian: Mở rộng chiến lược đến nhiều công cụ giao dịch và khung thời gian và cải thiện khả năng thích nghi và ổn định của chiến lược thông qua đầu tư đa dạng và tối ưu hóa khung thời gian.
Chiến lược EMA Cross ADR là một chiến lược giao dịch định lượng dựa trên phân tích kỹ thuật. Nó xác định xu hướng thông qua hai đường chéo EMA và sử dụng chỉ số ADR để lọc biến động. Chiến lược cũng thiết lập các biện pháp kiểm soát rủi ro nghiêm ngặt, bao gồm dừng lỗ và lấy lợi nhuận động, dừng phá vỡ và giới hạn lỗ hàng ngày tối đa để kiểm soát rủi ro giảm. Những lợi thế của chiến lược nằm trong khả năng theo dõi xu hướng mạnh mẽ, khả năng thích ứng biến động tốt, kiểm soát rủi ro nghiêm ngặt, cài đặt tham số linh hoạt và mức độ tự động cao. Tuy nhiên, nó cũng có một số rủi ro, chẳng hạn như rủi ro tối ưu hóa tham số, rủi ro sự kiện đột ngột, rủi ro đảo ngược xu hướng, rủi ro thanh khoản và rủi ro thất bại chỉ số kỹ thuật. Trong tương lai, chiến lược có thể xem xét và tối ưu hóa từ nhiều khía cạnh thực tế như giới thiệu các chỉ số định số, tối ưu hóa tham số động, kết hợp các yếu tố cơ bản yếu, tăng cường cơ chế dừng lỗ và cơ chế giao dịch, mở rộng và nâng cao độ lợi nhuận theo thời
/*backtest start: 2024-02-26 00:00:00 end: 2024-03-27 00:00:00 period: 2h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © Sameh_Hussein //@version=5 strategy('EMA Cross ADR Strategy with Stats', overlay=true) // Adjustable Parameters shortEmaLength = input(10, title='Short EMA Length') longEmaLength = input(50, title='Long EMA Length') adrLength = input(14, title='ADR Length') riskRewardRatio = input(2.0, title='Risk/Reward Ratio') lookbackCandles = input(10, title='Lookback Candles for Stop Loss') startTime = input(0900, title='Start Time') endTime = input(1600, title='End Time') minAdrValue = input(10, title='Minimum ADR Value for Entry') breakEvenProfit = input.float(1.0, title='Break-Even Profit', minval=0.0) breakEvenRR = input.float(1.0, title='Break-Even Risk-Reward Ratio', minval=0.0) dailyLossLimit = input(-2000.0, title='Daily Loss Limit') // Exponential Moving Averages shortEma = ta.ema(close, shortEmaLength) longEma = ta.ema(close, longEmaLength) // Average Daily Range adr = ta.sma(ta.tr, adrLength) // Time Filter Function timeFilter() => true // Entry Conditions with ADR filter longCondition = ta.crossover(shortEma, longEma) and timeFilter() and adr > minAdrValue shortCondition = ta.crossunder(shortEma, longEma) and timeFilter() and adr > minAdrValue // Calculate the average low and average high of the previous 'lookbackCandles' candles averageLow = ta.sma(low, lookbackCandles) averageHigh = ta.sma(high, lookbackCandles) // Risk and Reward Calculation stopLossLong = averageLow takeProfitLong = close + (close - averageLow) * riskRewardRatio stopLossShort = averageHigh takeProfitShort = close - (averageHigh - close) * riskRewardRatio // Entry Control Variables var longEntryAllowed = true var shortEntryAllowed = true // Update entry price on trade execution var float entryPriceLong = na var float entryPriceShort = na if (strategy.position_size > 0) if (strategy.position_size[1] <= 0) entryPriceLong := strategy.opentrades.entry_price(strategy.opentrades - 1) else entryPriceLong := entryPriceLong else entryPriceLong := na if (strategy.position_size < 0) if (strategy.position_size[1] >= 0) entryPriceShort := strategy.opentrades.entry_price(strategy.opentrades - 1) else entryPriceShort := entryPriceShort else entryPriceShort := na // Adjust stop loss to break-even plus the defined profit when the specified risk-reward ratio is reached breakEvenTriggerLong = entryPriceLong + (entryPriceLong - stopLossLong) * breakEvenRR breakEvenTriggerShort = entryPriceShort - (stopLossShort - entryPriceShort) * breakEvenRR if (longEntryAllowed and close >= breakEvenTriggerLong) stopLossLong := entryPriceLong + breakEvenProfit if (shortEntryAllowed and close <= breakEvenTriggerShort) stopLossShort := entryPriceShort - breakEvenProfit // Close all trades at 1600 if (hour == 15 and minute == 59) strategy.close_all(comment='Close at 1600') // Define the daily loss variable and last trade day var float[] dailyLossArray = array.new_float(1, 0.0) var int[] lastTradeDayArray = array.new_int(1, na) // Function to update the daily loss updateDailyLoss() => _dailyLoss = array.get(dailyLossArray, 0) _lastTradeDay = array.get(lastTradeDayArray, 0) if na(_lastTradeDay) or dayofmonth != _lastTradeDay _dailyLoss := 0.0 array.set(lastTradeDayArray, 0, dayofmonth) if not na(strategy.closedtrades.entry_bar_index(strategy.closedtrades - 1)) _dailyLoss += strategy.closedtrades.profit(strategy.closedtrades - 1) array.set(dailyLossArray, 0, _dailyLoss) // Call the function to update the daily loss updateDailyLoss() // Execute Strategy if longCondition and longEntryAllowed strategy.entry('Long', strategy.long) strategy.exit('Take Profit/Stop Loss', 'Long', stop=stopLossLong, limit=takeProfitLong) longEntryAllowed := false if shortCondition and shortEntryAllowed strategy.entry('Short', strategy.short) strategy.exit('Take Profit/Stop Loss', 'Short', stop=stopLossShort, limit=takeProfitShort) shortEntryAllowed := false // Reset entry control variables on position close if strategy.position_size == 0 longEntryAllowed := true shortEntryAllowed := true // // Statistics // winRate = strategy.wintrades / strategy.closedtrades * 100 // totalTrades = strategy.closedtrades // averageProfit = strategy.grossprofit / strategy.wintrades // averageLoss = strategy.grossloss / strategy.losstrades // // Plotting // plot(shortEma, color=color.new(color.red, 0), title='Short EMA') // plot(longEma, color=color.new(color.blue, 0), title='Long EMA') // // Display Table // table statsTable = table.new(position=position.top_right, columns=2, rows=4, bgcolor=color.gray, border_width=1) // table.cell(statsTable, column=0, row=0, text='Win Rate (%)', bgcolor=color.blue) // table.cell(statsTable, column=1, row=0, text=str.tostring(winRate), bgcolor=color.blue) // table.cell(statsTable, column=0, row=1, text='Total Trades', bgcolor=color.blue) // table.cell(statsTable, column=1, row=1, text=str.tostring(totalTrades), bgcolor=color.blue) // table.cell(statsTable, column=0, row=2, text='Average Profit', bgcolor=color.blue) // table.cell(statsTable, column=1, row=2, text=str.tostring(averageProfit), bgcolor=color.blue) // table.cell(statsTable, column=0, row=3, text='Average Loss', bgcolor=color.blue) // table.cell(statsTable, column=1, row=3, text=str.tostring(averageLoss), bgcolor=color.blue)