Artikel ini memperkenalkan strategi perdagangan algoritmik yang mengidentifikasi peluang menguntungkan melalui pola engulfing dan menggunakan crossover harga dengan moving average sebagai sinyal masuk. Menggabungkan analisis teknis dengan metode trend berikut, strategi ini bertujuan untuk mendapatkan keuntungan pada titik konsolidasi dan pembalikan tren.
Logika inti dari strategi ini didasarkan pada konvergensi dua indikator yang tidak terkait:
Pola Menelan: Pola pembalikan dua candlestick di mana tubuh lilin kedua benar-benar menelan tubuh yang pertama, digunakan untuk mengidentifikasi peluang pembalikan.
Price Crossover with Moving Average: Sinyal beli dihasilkan ketika harga melintasi garis rata-rata bergerak dari bawah; Sinyal jual adalah ketika harga melintasi di bawah garis rata-rata bergerak dari atas.
Dengan menilai waktu potensi pembalikan pasar dengan pola engulfing dan menggunakan crossover harga dengan moving average sebagai sinyal konfirmasi, kemungkinan keuntungan dapat ditingkatkan.
Secara khusus, strategi ini melacak tiga jenis pola engulfing - bullish, bearish dan no shadow engulfing untuk menentukan kemungkinan konsolidasi dan pembalikan.
Keuntungan terbesar dari strategi ini adalah memanfaatkan konvergensi indikator yang tidak terkait untuk meningkatkan efektivitas keputusan. Pola engulfing menilai waktu dan probabilitas pembalikan pasar; sementara penyeberangan harga dengan moving average memverifikasi arah dan momentum pembalikan. Keduanya saling memvalidasi dan dapat secara efektif mengurangi kerugian perdagangan yang disebabkan oleh sinyal palsu.
Keuntungan lain adalah fleksibilitas pengaturan parameter. Pengguna dapat mengatur parameter seperti periode moving average dan stop loss range untuk mengoptimalkan strategi sendiri.
Meskipun menggunakan beberapa indikator meningkatkan penilaian, masih ada beberapa risiko sinyal palsu dalam strategi ini. pola engulfing tidak 100% sinyal pembalikan yang dapat diandalkan, dan skenario kegagalan juga ada dalam penyeberangan harga dengan moving average. semua ini dapat menyebabkan kerugian dari posisi pembukaan prematur.
Selain itu, seperti kebanyakan strategi analisis teknis, juga berkinerja buruk dalam pasar tren yang bertentangan seperti rentang dan konsolidasi.
Untuk mengontrol risiko, parameter seperti periode rata-rata bergerak dan rentang stop loss dapat disesuaikan. indikator lain juga dapat dipertimbangkan untuk mengidentifikasi tren dan pasar sisi, sehingga partisipasi strategi dapat dikelola secara dinamis.
Bidang berikut dapat dioptimalkan untuk strategi ini:
Uji lebih banyak jenis rata-rata bergerak untuk menemukan set parameter yang optimal, seperti rata-rata bergerak tertimbang, rata-rata bergerak berimbang ganda dll.
Tambahkan indikator penilaian tren untuk menghindari membuka posisi di pasar sisi. Contoh adalah ADX, Bollinger Bands dll.
Mengoptimalkan metode stop loss untuk meningkatkan efektivitas.
Meningkatkan metode pembelajaran mesin untuk menilai pola candlestick dan meningkatkan akurasi pengenalan engulfing.
Tambahkan fungsi optimasi parameter untuk penyesuaian adaptif.
Strategi ini mengidentifikasi reversal timing dengan pola engulfing dan memverifikasi arah menggunakan price crossover dengan moving average. Dengan meningkatkan efektivitas keputusan melalui konvergensi indikator, ini adalah pendekatan analisis teknis. Keuntungan termasuk indikator komplementer dan parameter fleksibel. Kelemahan adalah risiko sinyal palsu dan kelemahan di pasar sampingan. Cara untuk lebih meningkatkan strategi ini termasuk mengoptimalkan parameter moving average, metode stop loss, menambahkan indikator penyaringan tren dll.
/*backtest start: 2023-12-30 00:00:00 end: 2024-01-29 00:00:00 period: 3h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 //@author=Daveatt StrategyName = "BEST Engulfing + MA" ShortStrategyName = "BEST Engulfing + MA" strategy(title=StrategyName, shorttitle=ShortStrategyName, overlay=true) includeEngulfing = true includeMA = true source_ma = input(title="Source Price vs MA", type=input.source, defval=close) typeofMA = input(title="Type of MA", defval="SMA", options=["RMA", "SMA", "EMA", "WMA", "VWMA", "SMMA", "KMA", "TMA", "HullMA", "DEMA", "TEMA"]) length_ma = input(32, title = "MA Length", type=input.integer) // ---------- Candle components and states GreenCandle = close > open RedCandle = close < open NoBody = close==open Body = abs(close-open) // bullish conditions isBullishEngulfing1 = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and GreenCandle and RedCandle[1] isBullishEngulfing2 = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) <= min(close,open) and Body > Body[1] and GreenCandle and RedCandle[1] // bearish conditions isBearishEngulfing1 = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and RedCandle and GreenCandle[1] isBearishEngulfing2 = max(close[1],open[1]) >= max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and RedCandle and GreenCandle[1] // consolidation of conditions isBullishEngulfing = isBullishEngulfing1 or isBullishEngulfing2 isBearishEngulfing = isBearishEngulfing1 or isBearishEngulfing2 //isBullishEngulfing = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and GreenCandle and RedCandle[1] //isBearishEngulfing = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and RedCandle and GreenCandle[1] Engulf_curr = 0 - barssince(isBearishEngulfing) + barssince(isBullishEngulfing) Engulf_Buy = Engulf_curr < 0 ? 1 : 0 Engulf_Sell = Engulf_curr > 0 ? 1 : 0 // Price vs MM smma(src, len) => smma = 0.0 smma := na(smma[1]) ? sma(src, len) : (smma[1] * (len - 1) + src) / len smma ma(smoothing, src, length) => if smoothing == "RMA" rma(src, length) else if smoothing == "SMA" sma(src, length) else if smoothing == "EMA" ema(src, length) else if smoothing == "WMA" wma(src, length) else if smoothing == "VWMA" vwma(src, length) else if smoothing == "SMMA" smma(src, length) else if smoothing == "HullMA" wma(2 * wma(src, length / 2) - wma(src, length), round(sqrt(length))) else if smoothing == "LSMA" src else if smoothing == "KMA" xPrice = src xvnoise = abs(xPrice - xPrice[1]) nfastend = 0.666 nslowend = 0.0645 nsignal = abs(xPrice - xPrice[length]) nnoise = sum(xvnoise, length) nefratio = iff(nnoise != 0, nsignal / nnoise, 0) nsmooth = pow(nefratio * (nfastend - nslowend) + nslowend, 2) nAMA = 0.0 nAMA := nz(nAMA[1]) + nsmooth * (xPrice - nz(nAMA[1])) nAMA else if smoothing == "TMA" sma(sma(close, length), length) else if smoothing == "DEMA" 2 * src - ema(src, length) else if smoothing == "TEMA" 3 * (src - ema(src, length)) + ema(ema(src, length), length) else src MA = ma(typeofMA, source_ma, length_ma) plot(MA, color=#006400FF, title="MA breakout", linewidth=3) macrossover = crossover (source_ma, MA) macrossunder = crossunder(source_ma, MA) since_ma_buy = barssince(macrossover) since_ma_sell = barssince(macrossunder) macross_curr = 0 - since_ma_sell + since_ma_buy bullish_MA_cond = macross_curr < 0 ? 1 : 0 bearish_MA_cond = macross_curr > 0 ? 1 : 0 posUp = (Engulf_Buy ? 1 : 0) + (bullish_MA_cond ? 1 : 0) posDn = (Engulf_Sell ? 1 : 0) + (bearish_MA_cond ? 1 : 0) conditionUP = posUp == 2 and posUp[1] < 2 conditionDN = posDn == 2 and posDn[1] < 2 sinceUP = barssince(conditionUP) sinceDN = barssince(conditionDN) // primary-first signal of the trend nUP = crossunder(sinceUP,sinceDN) nDN = crossover(sinceUP,sinceDN) // and the following secondary signals // save of the primary signal sinceNUP = barssince(nUP) sinceNDN = barssince(nDN) buy_trend = sinceNDN > sinceNUP sell_trend = sinceNDN < sinceNUP // engulfing by barcolor(nUP ? color.orange : na, title="Bullish condition") barcolor(nDN ? color.yellow : na, title="Bearish condition") isLong = nUP isShort = nDN long_entry_price = valuewhen(nUP, close, 0) short_entry_price = valuewhen(nDN, close, 0) longClose = close[1] < MA shortClose = close[1] > MA /////////////////////////////////////////////// //* Backtesting Period Selector | Component *// /////////////////////////////////////////////// StartYear = input(2017, "Backtest Start Year",minval=1980) StartMonth = input(1, "Backtest Start Month",minval=1,maxval=12) StartDay = input(1, "Backtest Start Day",minval=1,maxval=31) testPeriodStart = timestamp(StartYear,StartMonth,StartDay,0,0) StopYear = input(2020, "Backtest Stop Year",minval=1980) StopMonth = input(12, "Backtest Stop Month",minval=1,maxval=12) StopDay = input(31, "Backtest Stop Day",minval=1,maxval=31) testPeriodStop = timestamp(StopYear,StopMonth,StopDay,0,0) testPeriod() => true ////////////////////////// //* Profit Component *// ////////////////////////// input_tp_pips = input(600, "Backtest Profit Goal (in USD)",minval=0) input_sl_pips = input(300, "Backtest STOP Goal (in USD)",minval=0) tp = buy_trend? long_entry_price + input_tp_pips : short_entry_price - input_tp_pips sl = buy_trend? long_entry_price - input_sl_pips : short_entry_price + input_sl_pips long_TP_exit = buy_trend and high >= tp short_TP_exit = sell_trend and low <= tp plot(tp, title="TP", style=plot.style_circles, linewidth=3, color=color.blue) plot(sl, title="SL", style=plot.style_circles, linewidth=3, color=color.red) if testPeriod() strategy.entry("Long", 1, when=isLong) strategy.close("Long", when=longClose ) strategy.exit("XL","Long", limit=tp, when=buy_trend, stop=sl) if testPeriod() strategy.entry("Short", 0, when=isShort) strategy.close("Short", when=shortClose ) strategy.exit("XS","Short", when=sell_trend, limit=tp, stop=sl)