Chiến lược đa yếu tố tích hợp các chiến lược dao động, theo xu hướng và đột phá vào một bằng cách kết hợp các điểm mạnh của chúng. Điều này cho phép đạt được hiệu suất tốt hơn trong các điều kiện thị trường khác nhau.
Chiến lược đa yếu tố được mô hình hóa chủ yếu dựa trên các khía cạnh sau:
Phần dao động sử dụng dao động Stochastic để xác định tín hiệu mua và bán. Cụ thể, tín hiệu mua được tạo ra khi đường %K vượt qua đường %D từ vùng bán quá mức.
Một tín hiệu mua được tạo ra khi SMA nhanh vượt qua trên SMA chậm. Một tín hiệu bán được tạo ra khi SMA nhanh vượt qua dưới SMA chậm.
Phần phá vỡ theo dõi xem giá có vượt quá mức giá cao nhất hoặc giảm xuống dưới mức giá thấp nhất trong một khoảng thời gian nhất định. Nó sẽ kích hoạt mua khi giá vượt qua mức giá cao nhất và bán khi giá giảm xuống dưới mức giá thấp nhất.
Chỉ số ADX được sử dụng để đo sức mạnh của xu hướng.
Các đường dừng lỗ và lấy lợi nhuận được thực hiện để tối ưu hóa lợi nhuận.
Tóm lại, chiến lược đa yếu tố theo logic dưới đây:
Khi ADX trên ngưỡng, xu hướng được coi là mạnh. Chiến lược theo xu hướng có hiệu lực. Khi ADX dưới ngưỡng, thị trường đang dao động. Chỉ có chiến lược dao động có hiệu lực.
Trong một thị trường xu hướng, đường chéo vàng SMA kích hoạt bước vào dài và đường chéo chết kích hoạt bước ra khỏi các vị trí.
Trong thị trường dao động, các tín hiệu giao dịch từ dao động Stochastic được theo dõi.
Chiến lược phá vỡ áp dụng trong cả hai điều kiện thị trường để theo đuổi đà tăng mạnh.
Các đường dừng lỗ và lấy lợi nhuận được thiết lập để khóa lợi nhuận và hạn chế lỗ.
Ưu điểm lớn nhất của chiến lược đa yếu tố là nó kết hợp các điểm mạnh của các chiến lược khác nhau và đạt được hiệu suất tốt trên cả thị trường xu hướng và thị trường dao động.
Nó chạy theo xu hướng tốt và đạt được tỷ lệ thắng cao trong các thị trường xu hướng.
Nó có thể lợi nhuận từ các thị trường giới hạn và tránh bị mắc kẹt trong các vị trí.
Nó có yếu tố lợi nhuận cao với việc đặt đúng mức dừng lỗ và lấy lợi nhuận.
Nó xem xét sức mạnh xu hướng để giảm tổn thất từ các tín hiệu sai.
Sự kết hợp của nhiều chỉ số dẫn đến các tín hiệu giao dịch mạnh mẽ.
Các thông số có thể được tối ưu hóa để có hiệu suất tốt hơn.
Ngoài ra còn có những rủi ro liên quan đến chiến lược đa yếu tố:
Sự kết hợp không đúng của các yếu tố có thể dẫn đến các tín hiệu giao dịch mâu thuẫn.
Nhiều tham số làm tăng khó khăn của tối ưu hóa và yêu cầu đủ dữ liệu lịch sử.
Nó có thể không thoát khỏi các vị trí kịp thời khi xu hướng đảo ngược, dẫn đến tổn thất lớn.
Chỉ số ADX có hiệu ứng chậm và có thể bỏ lỡ các điểm chuyển hướng.
Giao dịch đột phá có xu hướng bị mắc kẹt trong các vị trí thua lỗ.
Các rủi ro có thể được giảm thiểu thông qua:
Kiểm tra lại sự ổn định của các yếu tố và chọn những yếu tố ổn định.
Sử dụng thuật toán tối ưu hóa heuristic để tìm các thông số tối ưu.
Thiết lập stop loss thích hợp để kiểm soát mức rút tối đa.
Bao gồm các chỉ số bổ sung để phát hiện sự đảo ngược xu hướng.
Tối ưu hóa các quy tắc dừng lỗ cho giao dịch thoát.
Vẫn còn chỗ để cải thiện chiến lược đa yếu tố:
Kiểm tra nhiều loại yếu tố như biến động, khối lượng vv để tìm kết hợp tốt hơn.
Sử dụng các kỹ thuật học máy để tối ưu hóa trọng lượng yếu tố một cách năng động.
Tận dụng các thuật toán thuyết phục để tối ưu hóa tham số nhanh chóng.
Kiểm tra lợi nhuận trong các giai đoạn nắm giữ khác nhau.
Khám phá các quy tắc dừng lỗ động. Ví dụ, mở rộng dừng lỗ sau khi kiếm được một số lợi nhuận.
Thêm thêm các bộ lọc như âm lượng tăng để cải thiện chất lượng tín hiệu.
Tối ưu hóa các thông số ADX hoặc sử dụng các chỉ số phát hiện xu hướng tiên tiến hơn.
Chiến lược đa yếu tố kết hợp nhiều logic giao dịch như xu hướng, đảo ngược trung bình và đột phá. Nó đạt được hiệu suất tốt trong cả thị trường xu hướng và dao động. So với các chiến lược một yếu tố, nó cung cấp lợi nhuận ổn định hơn và có tiềm năng nâng cấp lớn. Tuy nhiên, tối ưu hóa tham số có thể khó khăn và đòi hỏi đủ dữ liệu lịch sử. Nhìn chung, chiến lược đa yếu tố là một kỹ thuật giao dịch thuật toán rất hiệu quả đáng nghiên cứu và tối ưu hóa hơn nữa.
/*backtest start: 2023-09-30 00:00:00 end: 2023-10-30 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 // strategy("Strategy_1", shorttitle="Strategy1",overlay=true ,pyramiding = 12, initial_capital=25000, currency='EUR', commission_type = strategy.commission.cash_per_order, commission_value = 3, default_qty_type = strategy.percent_of_equity, default_qty_value = 20) // Revision: 1 // Author: Jonas // === INPUT === // > BACKTEST RANGE < FromMonth = input(defval=1, title="From Month", minval=1, maxval=12) FromDay = input(defval=1, title="From Day", minval=1, maxval=31) FromYear = input(defval=2017, title="From Year", minval=2010) ToMonth = input(defval=1, title="To Month", minval=1, maxval=12) ToDay = input(defval=1, title="To Day", minval=1, maxval=31) ToYear = input(defval=9999, title="To Year", minval=2010) // > STRATEGY SETTINGS < bolOS = input(defval = false, type=input.bool, title="Oscillating Strategy") bolTS = input(defval = true, type=input.bool, title="Trend Strategy") bolBO = input(defval = false, type=input.bool, title="Breakout Strategy") strStrategy = input(defval = "Long", type=input.string, title="Trade Strategy",options = ["Long", "Short","Long & Short"]) flStopLoss = input(defval = 2.0, title="Stop Loss %", type=input.float)/100 flTakeProfit = input(defval = 4.0, title="Take Profit %", type=input.float)/100 // > SMA < fastMA = input(defval=8, type=input.integer, title="FastMA length", minval=1, step=1) slowMA = input(defval=21, type=input.integer, title="SlowMA length", minval=1, step=1) // > ADX < adx_len = input(defval=10, type=input.integer, title="ADX length", minval=1, step=1) adx_trend = input(defval=30, type=input.integer, title="ADX Tr", minval=1, step=1) adx_choppy = adx_trend adx_limit = adx_trend // > TRENDSCORE < ts_fromIndex = input(title="From", type=input.integer, minval=1, defval=10) ts_toIndex = input(title="To", type=input.integer, minval=1, defval=14) ts_src = input(title="Source", type=input.source, defval=close) // > Oscillator < stoch_length = 14 stoch_OverBought = 75 stoch_OverSold = 25 stoch_smoothK = 3 stoch_smoothD = 3 // === BACK TEST RANGE FUNCTION === window_start = timestamp(FromYear, FromMonth, FromDay, 00, 00) // backtest start window window_finish = timestamp(ToYear, ToMonth, ToDay, 23, 59) // backtest finish window window() => // create function "within window of time" time >= window_start and time <= window_finish ? true : false //plot(stop_level_Long, title="TEST",color=color.red, style=plot.style_linebr, linewidth=2) //plot(take_level_Long, color=color.green, style=plot.style_linebr, linewidth=2) // === ADX === adx_up = change(high) adx_down = -change(low) adx_trur = rma(tr, adx_len) adx_plus = fixnan(100 * rma(adx_up > adx_down and adx_up > 0 ? adx_up : 0, adx_len) / adx_trur) adx_minus = fixnan(100 * rma(adx_down > adx_up and adx_down > 0 ? adx_down : 0, adx_len) / adx_trur) adx_sum = adx_plus + adx_minus ADX = 100 * rma(abs(adx_plus - adx_minus) / (adx_sum == 0 ? 1 : adx_sum), adx_len) //=== TRENDSCORE === trendscore(ts_src, ts_fromIndex, ts_toIndex) => ts_sum = 0.0 for i = ts_fromIndex to ts_toIndex ts_sum := ts_sum + (ts_src >= nz(ts_src[i]) ? 1 : -1) ts_sum intTS = trendscore(ts_src, ts_fromIndex, ts_toIndex) // Long if TrendDirection = 1, Short if TrendDirection = -1; Indifferent if TrendDirection = 0 intTrendDirection = (intTS > (ts_toIndex-ts_fromIndex)) ? 1 : (intTS < (ts_fromIndex-ts_toIndex)) ? -1 : 0 // > TREND CONDITION < adx_growing = ADX > highest(ADX[1],3) intTrend = ((ADX >= adx_limit) and (ADX[1] >= adx_limit) and adx_growing) ? intTrendDirection : 0 // === ATR === ATR = sma(tr,10) ATR_100 = ATR /abs(high - low) // === STOCHASTICS === stoch_k = sma(stoch(close, high, low, stoch_length), stoch_smoothK) stoch_d = sma(stoch_k, stoch_smoothD) // === FILTER & CONDITIONS === // > STOCHASTICS < bolFilter_OS1 = close[1] > hl2[1] bolSigOsc_long_1 = (na(stoch_k) or na(stoch_d)) ? false : (crossover(stoch_d,stoch_OverSold) and stoch_k > stoch_d) ? true:false bolSigOsc_short_1 = (na(stoch_k) or na(stoch_d)) ? false : (crossunder(stoch_d,stoch_OverBought) and stoch_k < stoch_d) ? true:false bolLongOpenOS = bolSigOsc_long_1 and bolFilter_OS1 bolLongCloseOS = bolSigOsc_short_1 bolShortOpenOS = bolSigOsc_short_1 and bolFilter_OS1 bolShortCloseOS = bolSigOsc_long_1 // > TREND < bolFilter_TS1 = close[1] > hl2[1] and open[1] < hl2[1] bolFilter_TS2 = sma(close,50)>sma(close,50)[10] bolFilter_TS3 = close[1] < hl2[1] and open[1] > hl2[1] bolSigTrendLO1 = sma(close, fastMA) > sma(close, slowMA) bolSigTrendLO2 = close > sma(close,fastMA) bolSigTrendLO3 = bolSigTrendLO1 and bolSigTrendLO2 bolSigTrendLC1 = sma(close, fastMA) < sma(close, slowMA) bolSigTrendLC2 = close < sma(close, fastMA) bolSigTrendLC3 = bolSigTrendLC1 and bolSigTrendLC2 bolSigTrendSO1 = bolSigTrendLC3 bolSigTrendSC1 = bolSigTrendLO1 bolLongOpenTS = bolSigTrendLO3 and bolFilter_TS1 bolLongCloseTS = bolSigTrendLC3 and bolFilter_TS3 bolShortOpenTS = bolSigTrendSO1 and bolFilter_TS3 bolShortCloseTS = bolLongOpenTS and bolFilter_TS1 plot(sma(close, fastMA), title='FastMA', color=color.green, linewidth=2, style=plot.style_line) // plot FastMA plot(sma(close, slowMA), title='SlowMA', color=color.red, linewidth=2, style=plot.style_line) // plot SlowMA // > BREAKOUT < flFilter_BS1 = 0.5 * stdev(close,slowMA)[1] bolFilter_BS2 = volume > sma(volume,slowMA)*1.25 bolSigBreakoutLO1 = close > (highestbars(high,slowMA)[1] + flFilter_BS1) bolSigBreakoutLC1 = barssince(bolSigBreakoutLO1)==5 bolSigBreakoutSO1 = close < lowestbars(low,slowMA)[1] - flFilter_BS1 bolSigBreakoutSC1 = barssince(bolSigBreakoutSO1)==5 bolLongOpenBO = bolSigBreakoutLO1 and bolFilter_BS2 bolLongCloseBO = bolSigBreakoutLC1 bolShortOpenBO = bolSigBreakoutSO1 and bolFilter_BS2 bolShortCloseBO = bolSigBreakoutSC1 //=== STRATEGIES ENTRIES & EXITS === // > STOPS & LIMITS < stop_level_Long = strategy.position_avg_price * (1 - flStopLoss) take_level_Long = strategy.position_avg_price * (1 + flTakeProfit) stop_level_Short = strategy.position_avg_price * (1 + flStopLoss) take_level_Short = strategy.position_avg_price * (1 - flTakeProfit) // > ENTRIES / CLOSES / EXITS < if window() //only in backtest-window if (bolOS == true) if (intTrend == 0) if(strStrategy == "Long" or strStrategy == "Long & Short") strategy.entry("Lng Osc", strategy.long, when=bolLongOpenOS) // buy long when "within window of time" AND crossover if(strStrategy == "Short" or strStrategy == "Long & Short") strategy.entry("Short Osc", strategy.short, when=bolShortOpenOS) strategy.close("Lng Osc", when=(bolLongCloseOS)) //strategy.exit("Exit L OS/STD", "Lng Osc", stop = strategy.position_avg_price - 2*stdev(close,10)) strategy.exit("Exit L OS/%", "Lng Osc", stop=stop_level_Long) strategy.close("Short Osc", when=(bolShortCloseOS)) //strategy.exit("Exit S OS/STD", "Short Osc", stop = strategy.position_avg_price + 2*stdev(strategy.position_avg_price,10)) strategy.exit("Exit S OS/%", "Short Osc", stop=stop_level_Short) if (bolTS == true) if (not(intTrend == 0)) if((strStrategy == "Long") or (strStrategy == "Long & Short")) strategy.entry("Lng TD", strategy.long, when=bolLongOpenTS) // buy long when "within window of time" AND crossover if((strStrategy == "Short") or (strStrategy == "Long & Short")) strategy.entry("Short TD", strategy.short, when=(bolShortOpenTS and bolTS)) // buy long when "within window of time" AND crossover strategy.exit("Exit L TD", "Lng TD", stop=stop_level_Long) strategy.close("Lng TD", when=bolLongCloseTS) strategy.exit("Exit S TD", "Short TD", stop=stop_level_Short) strategy.close("Short TD", when=bolShortCloseTS) if (bolBO == true) if((strStrategy == "Long") or (strStrategy == "Long & Short")) strategy.entry("Lng BO", strategy.long, when=bolLongOpenBO) // buy long when "within window of time" AND crossover strategy.close("Lng BO", when=bolLongCloseBO) //strategy.exit("Exit L BO/STD", "Lng BO", stop = strategy.position_avg_price - 2*stdev(strategy.position_avg_price,10)) strategy.exit("Exit L BO/2.5%", "Lng BO", stop=stop_level_Long) if((strStrategy == "Short") or (strStrategy == "Long & Short")) strategy.entry("Short BO", strategy.short, when=bolShortOpenBO) // buy long when "within window of time" AND crossover strategy.close("Short BO", when=bolShortCloseBO) //strategy.exit("Exit S BO/STD", "Short BO", stop = strategy.position_avg_price - 2*stdev(strategy.position_avg_price,10)) strategy.exit("Exit S BO/%", "Short BO", stop=stop_level_Short)