Trend Mengikut Strategi Berdasarkan Indikator Hull MA dan STC

Penulis:ChaoZhang, Tarikh: 2023-10-07 10:20:06
Tag:

Ringkasan

Strategi ini menggabungkan Hull MA rata-rata bergerak lancar dan penunjuk STC untuk mengesan trend dengan tepat. Ia menjadi panjang apabila garis Hull MA berubah menjadi hijau dan penunjuk STC berubah dari merah menjadi hijau dan di bawah 25; ia menjadi pendek apabila garis Hull MA berubah menjadi merah dan penunjuk STC berubah dari hijau menjadi merah dan di atas 75. Sementara itu, strategi ini juga mengintegrasikan penunjuk UT Bot untuk mengesahkan lebih lanjut isyarat trend.

Logika Strategi

Strategi ini menggunakan garis purata bergerak Hull MA untuk menentukan arah trend harga. Perubahan warna garis Hull MA dari hijau ke merah atau sebaliknya boleh digunakan untuk menilai pembalikan trend.

Indikator STC serupa dengan indikator MACD. Garis indikatornya boleh digunakan untuk menentukan pembalikan bullish / bearish. Apabila garis indikator melanggar di atas 25 dari bawah, ia adalah isyarat beli; apabila ia melanggar di bawah 75 dari atas, ia adalah isyarat jual.

Dengan menggabungkan penunjuk Hull MA dan STC, apabila kedua-dua penunjuk secara serentak menghasilkan isyarat beli/jual, ia menunjukkan pembalikan trend untuk kemasukan perdagangan.

Di samping itu, strategi ini juga menggabungkan penunjuk UT Bot, yang mengeluarkan bias menaik / menurun berdasarkan hubungan harga dengan garis stop loss dinamik berdasarkan ATR, untuk mengesahkan isyarat trend.

Secara khusus, logik strategi adalah:

  1. Apabila garis Hull MA menjadi hijau dan garis penunjuk STC berubah dari merah ke hijau, di bawah 25, ia adalah isyarat panjang.

  2. Apabila garis MA Hull berubah menjadi merah dan garis penunjuk STC berubah dari hijau ke merah, di atas 75, ia adalah isyarat pendek.

  3. Apabila kriteria di atas dipenuhi, memerlukan UT Bot menunjukkan kenaikan untuk membuka kedudukan panjang.

  4. Apabila kriteria di atas dipenuhi, memerlukan UT Bot menunjukkan penurunan untuk membuka kedudukan pendek.

Analisis Kelebihan

Strategi ini menggabungkan 3 penunjuk untuk menentukan trend, yang boleh meningkatkan kebolehpercayaan isyarat.

Kurva MA Hull yang lancar dapat menentukan arah trend dengan tepat dan mengelakkan whipsaws. Indikator STC dapat menangkap titik pembalikan trend untuk meningkatkan prestasi masa nyata strategi. UT Bot dapat menapis isyarat palsu.

Gabungan ketiga-tiga penunjuk membolehkan pengesanan trend yang tepat sambil meningkatkan kestabilan.

Analisis Risiko

Risiko utama strategi:

  1. Indikator STC cenderung menghasilkan isyarat palsu, menyebabkan entri yang tidak perlu.

  2. Tetapan parameter Hull MA yang salah juga boleh salah menilai trend.

  3. Gabungan yang tidak betul dari 3 penunjuk boleh mengganggu satu sama lain.

Risiko boleh dikurangkan dengan mengoptimumkan parameter Hull MA, menyesuaikan campuran parameter STC, menguji parameter UT Bot.

Di samping itu, stop loss boleh digunakan untuk mengawal kerugian perdagangan tunggal.

Arahan pengoptimuman

Strategi ini boleh dioptimumkan dalam aspek berikut:

  1. Mengoptimumkan parameter Hull MA untuk mencari panjang optimum untuk lengkung licin untuk menyesuaikan dengan trend yang lebih baik.

  2. Sesuaikan campuran parameter STC untuk mencari kombinasi yang lebih tepat untuk mengesan pembalikan.

  3. Mengoptimumkan parameter UT Bot untuk meningkatkan ketepatan penilaian trend.

  4. Ujian memperkenalkan penunjuk lain untuk pengesahan gabungan untuk meningkatkan kebolehpercayaan isyarat.

  5. Mengoptimumkan strategi stop loss untuk mengekalkan keuntungan sambil mengawal kerugian perdagangan tunggal dalam julat yang boleh diterima.

  6. Mengoptimumkan strategi saiz kedudukan untuk nisbah ganjaran / risiko yang lebih tinggi.

Kesimpulan

Strategi ini dengan tepat mengesan trend dengan menggabungkan penunjuk Hull MA, STC dan UT Bot. Ia mempunyai kelebihan kepelbagaian penunjuk, yang mengurangkan risiko salah menilai dan meningkatkan kestabilan. Strategi ini boleh ditingkatkan dengan terus mengoptimumkan parameter, memperkenalkan penunjuk lain, menyempurnakan strategi stop loss dan lain-lain.


/*backtest
start: 2023-09-06 00:00:00
end: 2023-10-06 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © myn

//@version=5
strategy('Strategy Myth-Busting #1 - UT Bot+STC+Hull+ [MYN]', max_bars_back=5000, overlay=true, pyramiding=0, initial_capital=20000, currency='USD', default_qty_type=strategy.percent_of_equity, default_qty_value=100.0, commission_value=0.075)




/////////////////////////////////////
//* Put your strategy logic below *//
/////////////////////////////////////
//2oVDibie_bk

/// UT Bot Alerts by QuantNomad - https://www.tradingview.com/script/n8ss8BID-UT-Bot-Alerts/
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
//study(title="UT Bot Alerts", overlay = true)

// Inputs
a = input(2, title='Key Vaule. \'This changes the sensitivity\'')
c = input(6, title='ATR Period')
h = input(false, title='Signals from Heikin Ashi Candles')

xATR = ta.atr(c)
nLoss = a * xATR

src = h ? request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, close, lookahead=barmerge.lookahead_off) : close

xATRTrailingStop = 0.0
iff_1 = src > nz(xATRTrailingStop[1], 0) ? src - nLoss : src + nLoss
iff_2 = src < nz(xATRTrailingStop[1], 0) and src[1] < nz(xATRTrailingStop[1], 0) ? math.min(nz(xATRTrailingStop[1]), src + nLoss) : iff_1
xATRTrailingStop := src > nz(xATRTrailingStop[1], 0) and src[1] > nz(xATRTrailingStop[1], 0) ? math.max(nz(xATRTrailingStop[1]), src - nLoss) : iff_2

pos = 0
iff_3 = src[1] > nz(xATRTrailingStop[1], 0) and src < nz(xATRTrailingStop[1], 0) ? -1 : nz(pos[1], 0)
pos := src[1] < nz(xATRTrailingStop[1], 0) and src > nz(xATRTrailingStop[1], 0) ? 1 : iff_3

xcolor = pos == -1 ? color.red : pos == 1 ? color.green : color.blue

ema = ta.ema(src, 1)
above = ta.crossover(ema, xATRTrailingStop)
below = ta.crossover(xATRTrailingStop, ema)

buy = src > xATRTrailingStop and above
sell = src < xATRTrailingStop and below

barbuy = src > xATRTrailingStop
barsell = src < xATRTrailingStop

//plotshape(buy,  title = "Buy",  text = 'Buy',  style = shape.labelup,   location = location.belowbar, color= color.green, textcolor = color.white, transp = 0, size = size.tiny)
//plotshape(sell, title = "Sell", text = 'Sell', style = shape.labeldown, location = location.abovebar, color= color.red,   textcolor = color.white, transp = 0, size = size.tiny)

barcolor(barbuy ? color.green : na)
barcolor(barsell ? color.red : na)

alertcondition(buy, 'UT Long', 'UT Long')
alertcondition(sell, 'UT Short', 'UT Short')

///////////////////////////////////////////////
//======[ Position Check (long/short) ]======//
///////////////////////////////////////////////

last_longCondition = float(na)
last_shortCondition = float(na)
last_longCondition := buy ? time : nz(last_longCondition[1])
last_shortCondition := sell ? time : nz(last_shortCondition[1])

in_longCondition = last_longCondition > last_shortCondition
in_shortCondition = last_shortCondition > last_longCondition


UTBotBuyZone = in_longCondition
UTBotSellZone = in_shortCondition



/// STC Indicator - A Better MACD [SHK] By shayankm - https://www.tradingview.com/script/WhRRThMI-STC-Indicator-A-Better-MACD-SHK/

// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
//[SHK] STC colored indicator
//https://www.tradingview.com/u/shayankm/

//indicator(title='[SHK] Schaff Trend Cycle (STC)', shorttitle='STC', overlay=false)
STCDivider = input(false, '░░░░░░░░░░░░░░░░░░░░░░░░░')
EEEEEE = input(80, 'Length')
BBBB = input(27, 'FastLength')
BBBBB = input(50, 'SlowLength')

AAAA(BBB, BBBB, BBBBB) =>
    fastMA = ta.ema(BBB, BBBB)
    slowMA = ta.ema(BBB, BBBBB)
    AAAA = fastMA - slowMA
    AAAA

AAAAA(EEEEEE, BBBB, BBBBB) =>
    AAA = input(0.5)
    var CCCCC = 0.0
    var DDD = 0.0
    var DDDDDD = 0.0
    var EEEEE = 0.0
    BBBBBB = AAAA(close, BBBB, BBBBB)
    CCC = ta.lowest(BBBBBB, EEEEEE)
    CCCC = ta.highest(BBBBBB, EEEEEE) - CCC
    CCCCC := CCCC > 0 ? (BBBBBB - CCC) / CCCC * 100 : nz(CCCCC[1])
    DDD := na(DDD[1]) ? CCCCC : DDD[1] + AAA * (CCCCC - DDD[1])
    DDDD = ta.lowest(DDD, EEEEEE)
    DDDDD = ta.highest(DDD, EEEEEE) - DDDD
    DDDDDD := DDDDD > 0 ? (DDD - DDDD) / DDDDD * 100 : nz(DDDDDD[1])
    EEEEE := na(EEEEE[1]) ? DDDDDD : EEEEE[1] + AAA * (DDDDDD - EEEEE[1])
    EEEEE

mAAAAA = AAAAA(EEEEEE, BBBB, BBBBB)
mColor = mAAAAA > mAAAAA[1] ? color.new(color.green, 20) : color.new(color.red, 20)



if mAAAAA[3] <= mAAAAA[2] and mAAAAA[2] > mAAAAA[1] and mAAAAA > 75
    alert('Red', alert.freq_once_per_bar)
if mAAAAA[3] >= mAAAAA[2] and mAAAAA[2] < mAAAAA[1] and mAAAAA < 25
    alert('Green', alert.freq_once_per_bar)


//plot(mAAAAA, color=mColor, title='STC', linewidth=2)

//ul = plot(25, color=color.new(color.white, 0 ))
//ll = plot(75, color=color.new(color.purple, 0))
//fill(ul, ll, color=color.new(color.gray, 96))

STCGreenAndBelow25AndRising = mAAAAA > mAAAAA[1] and mAAAAA < 25
STCRedAndAndAbove75AndFalling = mAAAAA < mAAAAA[1] and mAAAAA > 75

/// Hull Suite by InSilico
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
//Basic Hull Ma Pack tinkered by InSilico - https://www.tradingview.com/script/hg92pFwS-Hull-Suite/
//study("Hull Suite by InSilico", overlay=true)

HullDivider = input(false, '░░░░░░░░░░░░░░░░░░░░░░░░░')
//INPUT
srcHull = input(close, title='Source')
modeSwitch = input.string('Hma', title='Hull Variation', options=['Hma', 'Thma', 'Ehma'])
length = input(55, title='Length(180-200 for floating S/R , 55 for swing entry)')
lengthMult = input(1.0, title='Length multiplier (Used to view higher timeframes with straight band)')

useHtf = input(false, title='Show Hull MA from X timeframe? (good for scalping)')
htf = input.timeframe('240', title='Higher timeframe')

switchColor = input(true, 'Color Hull according to trend?')
candleCol = input(false, title='Color candles based on Hull\'s Trend?')
visualSwitch = input(true, title='Show as a Band?')
thicknesSwitch = input(1, title='Line Thickness')
transpSwitch = input.int(40, title='Band Transparency', step=5)

//FUNCTIONS
//HMA
HMA(_src, _length) =>
    ta.wma(2 * ta.wma(_src, _length / 2) - ta.wma(_src, _length), math.round(math.sqrt(_length)))
//EHMA    
EHMA(_src, _length) =>
    ta.ema(2 * ta.ema(_src, _length / 2) - ta.ema(_src, _length), math.round(math.sqrt(_length)))
//THMA    
THMA(_src, _length) =>
    ta.wma(ta.wma(_src, _length / 3) * 3 - ta.wma(_src, _length / 2) - ta.wma(_src, _length), _length)

//SWITCH
Mode(modeSwitch, src, len) =>
    modeSwitch == 'Hma' ? HMA(src, len) : modeSwitch == 'Ehma' ? EHMA(src, len) : modeSwitch == 'Thma' ? THMA(src, len / 2) : na

//OUT
_hull = Mode(modeSwitch, srcHull, int(length * lengthMult))
HULL = useHtf ? request.security(syminfo.ticker, htf, _hull) : _hull
MHULL = HULL[0]
SHULL = HULL[2]

//COLOR
hullColor = switchColor ? HULL > HULL[2] ? #00ff00 : #ff0000 : #ff9800

//PLOT
///< Frame
Fi1 = plot(MHULL, title='MHULL', color=hullColor, linewidth=thicknesSwitch, transp=50)
Fi2 = plot(visualSwitch ? SHULL : na, title='SHULL', color=hullColor, linewidth=thicknesSwitch, transp=50)
alertcondition(ta.crossover(MHULL, SHULL), title='Hull trending up.', message='Hull trending up.')
alertcondition(ta.crossover(SHULL, MHULL), title='Hull trending down.', message='Hull trending down.')
///< Ending Filler
fill(Fi1, Fi2, title='Band Filler', color=hullColor, transp=transpSwitch)
///BARCOLOR
barcolor(color=candleCol ? switchColor ? hullColor : na : na)

HullGreen = hullColor == #00ff00
HullRed = hullColor == #ff0000

//////////////////////////////////////
//* Put your strategy rules below *//
/////////////////////////////////////



longCondition = STCGreenAndBelow25AndRising and HullGreen and UTBotBuyZone
shortCondition = STCRedAndAndAbove75AndFalling and HullRed and UTBotSellZone

//define as 0 if do not want to use
closeLongCondition = 0
closeShortCondition = 0


//░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
useStartPeriodTime = input.bool(true, 'Start', group='Date Range', inline='Start Period')
startPeriodTime = input(timestamp('1 Jan 2019'), '', group='Date Range', inline='Start Period')
useEndPeriodTime = input.bool(true, 'End', group='Date Range', inline='End Period')
endPeriodTime = input(timestamp('31 Dec 2030'), '', group='Date Range', inline='End Period')

start = useStartPeriodTime ? startPeriodTime >= time : false
end = useEndPeriodTime ? endPeriodTime <= time : false
calcPeriod = not start and not end

// Trade Direction 
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
tradeDirection = input.string('Long and Short', title='Trade Direction', options=['Long and Short', 'Long Only', 'Short Only'], group='Trade Direction')

// Percent as Points
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
per(pcnt) =>
    strategy.position_size != 0 ? math.round(pcnt / 100 * strategy.position_avg_price / syminfo.mintick) : float(na)

// Take profit 1
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
tp1 = input.float(title='Take Profit 1 - Target %', defval=100, minval=0.0, step=0.5, group='Take Profit', inline='Take Profit 1')
q1 = input.int(title='% Of Position', defval=100, minval=0, group='Take Profit', inline='Take Profit 1')

// Take profit 2
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
tp2 = input.float(title='Take Profit 2 - Target %', defval=100, minval=0.0, step=0.5, group='Take Profit', inline='Take Profit 2')
q2 = input.int(title='% Of Position', defval=100, minval=0, group='Take Profit', inline='Take Profit 2')

// Take profit 3
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
tp3 = input.float(title='Take Profit 3 - Target %', defval=100, minval=0.0, step=0.5, group='Take Profit', inline='Take Profit 3')
q3 = input.int(title='% Of Position', defval=100, minval=0, group='Take Profit', inline='Take Profit 3')

// Take profit 4
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
tp4 = input.float(title='Take Profit 4 - Target %', defval=100, minval=0.0, step=0.5, group='Take Profit')

/// Stop Loss
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
stoplossPercent = input.float(title='Stop Loss (%)', defval=15, minval=0.01, group='Stop Loss') * 0.01
slLongClose = close < strategy.position_avg_price * (1 - stoplossPercent)
slShortClose = close > strategy.position_avg_price * (1 + stoplossPercent)

/// Leverage
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
leverage = input.float(1, 'Leverage', step=.5, group='Leverage')
contracts = math.min(math.max(.000001, strategy.equity / close * leverage), 1000000000)


/// Trade State Management
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

isInLongPosition = strategy.position_size > 0
isInShortPosition = strategy.position_size < 0

/// ProfitView Alert Syntax String Generation
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

alertSyntaxPrefix = input.string(defval='PV-AccountNameHere_Strategy-Name-Here', title='Alert Syntax Prefix', group='ProfitView Alert Syntax')
alertSyntaxBase = alertSyntaxPrefix + '\n#' + str.tostring(open) + ',' + str.tostring(high) + ',' + str.tostring(low) + ',' + str.tostring(close) + ',' + str.tostring(volume) + ','


/// Trade Execution
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

if calcPeriod
    if longCondition and tradeDirection != 'Short Only' and isInLongPosition == false
        strategy.entry('Long', strategy.long, qty=contracts)

        alert(message=alertSyntaxBase + 'side:long', freq=alert.freq_once_per_bar_close)

    if shortCondition and tradeDirection != 'Long Only' and isInShortPosition == false
        strategy.entry('Short', strategy.short, qty=contracts)

        alert(message=alertSyntaxBase + 'side:short', freq=alert.freq_once_per_bar_close)
    //Inspired by Multiple %% profit exits example By adolgo https://www.tradingview.com/script/kHhCik9f-Multiple-profit-exits-example/
    strategy.exit('TP1', qty_percent=q1, profit=per(tp1))
    strategy.exit('TP2', qty_percent=q2, profit=per(tp2))
    strategy.exit('TP3', qty_percent=q3, profit=per(tp3))
    strategy.exit('TP4', profit=per(tp4))

    strategy.close('Long', qty_percent=100, comment='SL Long', when=slLongClose)
    strategy.close('Short', qty_percent=100, comment='SL Short', when=slShortClose)

    strategy.close_all(when=closeLongCondition or closeShortCondition, comment='Close Postion')



Lebih lanjut