Artikel ini memperkenalkan strategi perdagangan algoritma yang mengenal pasti peluang yang menguntungkan melalui corak menelan dan menggunakan persilangan harga dengan purata bergerak sebagai isyarat kemasukan.
Logik teras strategi ini adalah berdasarkan konvergensi dua penunjuk yang tidak berkaitan:
Corak Engulfing: Corak pembalikan dua candlestick di mana badan lilin kedua sepenuhnya mengengulfs badan yang pertama, digunakan untuk mengenal pasti peluang pembalikan.
Crossover Harga dengan Purata Bergerak: Isyarat beli dihasilkan apabila harga melintasi di atas garis purata bergerak dari bawah; Isyarat jual adalah apabila harga melintasi di bawah garis purata bergerak dari atas.
Dengan menilai masa pembalikan pasaran yang berpotensi dengan corak meluap dan menggunakan persilangan harga dengan purata bergerak sebagai isyarat pengesahan, kebarangkalian keuntungan dapat ditingkatkan.
Secara khusus, strategi ini mengesan tiga jenis corak engulfing - bullish, bearish dan tidak engulfing bayangan untuk menentukan pengukuhan dan pembalikan yang mungkin. Bersama dengan tanda-tanda salib emas dan salib mati harga dan crossover purata bergerak, arah kedudukan pembukaan akhirnya ditentukan.
Kelebihan terbesar strategi ini adalah memanfaatkan konvergensi penunjuk yang tidak berkaitan untuk meningkatkan keberkesanan keputusan. corak engulfing menilai masa dan kebarangkalian pembalikan pasaran; sementara persilangan harga dengan purata bergerak mengesahkan arah dan momentum pembalikan. Kedua-duanya saling mengesahkan dan dapat mengurangkan kerugian perdagangan yang disebabkan oleh isyarat palsu.
Satu lagi kelebihan adalah fleksibiliti tetapan parameter. Pengguna boleh menetapkan parameter seperti tempoh purata bergerak dan julat stop loss untuk mengoptimumkan strategi sendiri.
Walaupun menggunakan pelbagai penunjuk meningkatkan penilaian, masih ada beberapa risiko isyarat palsu dalam strategi ini. corak engulfing bukan isyarat pembalikan yang boleh dipercayai 100%, dan senario kegagalan juga wujud dalam persilangan harga dengan purata bergerak. semua ini boleh menyebabkan kerugian dari kedudukan pembukaan yang terlalu awal.
Di samping itu, seperti kebanyakan strategi analisis teknikal, ia juga berprestasi buruk dalam pasaran trend yang bertentangan seperti julat dan penyatuan. Tindakan harga sampingan yang berpanjangan boleh mencetuskan stop loss atau membatasi ruang penangkapan keuntungan.
Untuk mengawal risiko, parameter seperti tempoh purata bergerak dan julat stop loss boleh diselaraskan dengan sewajarnya. penunjuk lain juga boleh dipertimbangkan untuk mengenal pasti pasaran trend dan sampingan, supaya penyertaan strategi dapat dikendalikan secara dinamik.
Bidang berikut boleh dioptimumkan untuk strategi ini:
Uji lebih banyak jenis purata bergerak untuk mencari set parameter yang optimum, seperti purata bergerak tertimbang, purata bergerak yang dihaluskan dua kali ganda dll.
Tambah penanda penilaian trend untuk mengelakkan membuka kedudukan di pasaran sampingan. Contoh adalah ADX, Bollinger Bands dll.
Mengoptimumkan kaedah stop loss untuk meningkatkan keberkesanan.
Meningkatkan kaedah pembelajaran mesin untuk menilai corak candlestick dan meningkatkan ketepatan pengenalan engulfing.
Tambah fungsi pengoptimuman parameter untuk pelarasan adaptif.
Strategi ini mengenal pasti masa pembalikan dengan corak menelan dan mengesahkan arah menggunakan persilangan harga dengan purata bergerak. Dengan meningkatkan keberkesanan keputusan melalui konvergensi penunjuk, ia adalah pendekatan analisis teknikal. Kelebihan termasuk penunjuk pelengkap dan parameter fleksibel. Kelemahan adalah risiko isyarat palsu dan kelemahan dalam pasaran sampingan. Cara untuk meningkatkan lagi strategi ini termasuk mengoptimumkan parameter purata bergerak, kaedah berhenti kerugian, menambah indikator penapisan trend dan sebagainya.
/*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)