Strategi Multi-Faktor

Penulis:ChaoZhang, Tanggal: 2023-10-31 15:45:39
Tag:

img

Gambaran umum

Strategi multi-faktor mengintegrasikan strategi osilasi, mengikuti tren, dan strategi breakout menjadi satu dengan menggabungkan kekuatan mereka.

Logika Strategi

Strategi multi-faktor terutama dimodelkan berdasarkan aspek-aspek berikut:

  • Bagian osilasi menggunakan osilator Stochastic untuk mengidentifikasi sinyal beli dan jual. Secara khusus, sinyal beli dihasilkan ketika garis %K melintasi garis %D dari zona oversold. Sinyal jual dihasilkan ketika garis %K melintasi di bawah garis %D dari zona overbought.

  • Bagian yang mengikuti tren menggunakan salib emas SMA untuk menentukan arah tren. Sinyal beli dihasilkan ketika SMA cepat melintasi SMA lambat. Sinyal jual dihasilkan ketika SMA cepat melintasi SMA lambat.

  • Bagian breakout memantau apakah harga pecah di atas harga tertinggi atau pecah di bawah harga terendah dalam periode tertentu. Ini akan memicu pembelian ketika harga pecah di atas harga tertinggi, dan penjualan ketika harga pecah di bawah harga terendah.

  • Indikator ADX digunakan untuk mengukur kekuatan tren.

  • Stop loss dan take profit line diterapkan untuk mengoptimalkan profitabilitas.

Singkatnya, strategi multi-faktor mengikuti logika di bawah ini:

  1. Ketika ADX berada di atas ambang batas, tren dianggap kuat. Strategi mengikuti tren berlaku. Ketika ADX berada di bawah ambang batas, pasar berkisar. Hanya strategi osilasi yang berlaku.

  2. Dalam pasar tren, SMA golden cross memicu masuk panjang dan death cross memicu keluar posisi.

  3. Dalam pasar ranging, sinyal perdagangan dari osilator Stochastic diikuti.

  4. Strategi breakout berlaku dalam kedua kondisi pasar untuk mengikuti momentum yang kuat.

  5. Stop loss dan take profit line diatur untuk mengunci keuntungan dan membatasi kerugian.

Analisis Keuntungan

Keuntungan terbesar dari strategi multi-faktor adalah bahwa ia menggabungkan kekuatan dari strategi yang berbeda dan mencapai kinerja yang baik di kedua pasar tren dan berkisar.

  1. Ini mengendarai tren dengan baik dan mencapai tingkat kemenangan yang tinggi di pasar tren.

  2. Ini dapat mendapatkan keuntungan dari pasar yang terikat rentang dan menghindari terjebak dalam posisi.

  3. Ini memiliki faktor keuntungan yang tinggi dengan stop loss yang diatur dengan benar dan mengambil keuntungan.

  4. Hal ini mempertimbangkan kekuatan tren untuk mengurangi kerugian dari sinyal palsu.

  5. Kombinasi dari beberapa indikator menghasilkan sinyal perdagangan yang kuat.

  6. Parameter dapat dioptimalkan untuk kinerja yang lebih baik.

Analisis Risiko

Ada juga risiko yang terkait dengan strategi multi-faktor:

  1. Kombinasi faktor yang tidak tepat dapat menyebabkan sinyal perdagangan yang bertentangan. pengujian ekstensif diperlukan untuk menemukan kombinasi yang optimal.

  2. Beberapa parameter meningkatkan kesulitan optimasi dan membutuhkan data historis yang cukup.

  3. Hal ini mungkin gagal untuk keluar posisi pada waktunya ketika tren berbalik, yang mengarah pada kerugian besar.

  4. Indikator ADX memiliki efek keterlambatan dan mungkin melewatkan titik balik tren.

  5. Perdagangan breakout cenderung terjebak dalam posisi yang rugi.

Risiko dapat dikurangi dengan:

  1. Memeriksa stabilitas faktor dan memilih yang stabil.

  2. Menggunakan algoritma optimasi heuristik untuk menemukan parameter optimal.

  3. Menetapkan stop loss yang tepat untuk mengontrol drawdown maksimum.

  4. Menggabungkan indikator tambahan untuk mendeteksi pembalikan tren.

  5. Mengoptimalkan aturan stop loss untuk perdagangan breakout.

Arah Peningkatan

Masih ada ruang untuk meningkatkan strategi multi-faktor:

  1. Mencoba lebih banyak jenis faktor seperti volatilitas, volume dll untuk menemukan kombinasi yang lebih baik.

  2. Menggunakan teknik pembelajaran mesin untuk mengoptimalkan bobot faktor secara dinamis.

  3. Memanfaatkan algoritma heuristik untuk optimasi parameter cepat.

  4. Memeriksa profitabilitas dalam periode kepemilikan yang berbeda.

  5. Menjelajahi aturan stop loss yang dinamis. misalnya, memperluas stop loss setelah membuat beberapa keuntungan.

  6. Menambahkan lebih banyak filter seperti lonjakan volume untuk meningkatkan kualitas sinyal.

  7. Mengoptimalkan parameter ADX atau menggunakan indikator deteksi tren yang lebih maju.

Kesimpulan

Strategi multi-faktor menggabungkan beberapa logika perdagangan seperti tren, mean-reversal, dan breakout. Strategi multi-faktor ini mencapai kinerja yang baik di kedua pasar tren dan rentang. Dibandingkan dengan strategi faktor tunggal, strategi ini memberikan pengembalian yang lebih stabil dan memiliki potensi peningkatan yang besar. Namun, optimasi parameter bisa sulit dan membutuhkan data historis yang cukup. Secara keseluruhan, strategi multi-faktor adalah teknik perdagangan algoritmik yang sangat efektif yang layak untuk penelitian dan optimasi lebih lanjut.


/*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)




Lebih banyak