Strategi Perdagangan Corak ABCD Terbaik dengan Pengesanan Stop Loss dan Take Profit

Penulis:ChaoZhang, Tarikh: 2024-02-19 11:22:48
Tag:

img

I. Ringkasan Strategi

Strategi ini dinamakan Best ABCD Pattern Strategy (dengan Stop Loss dan Take Profit Tracking) . Ia adalah strategi kuantitatif yang berdagang berdasarkan model corak harga ABCD yang jelas. Idea utama adalah untuk pergi panjang atau pendek mengikut arah corak ABCD selepas mengenal pasti model ABCD yang lengkap, dan menetapkan stop loss dan mengambil penjejakan keuntungan untuk menguruskan kedudukan.

II. Prinsip Strategi

  1. Mengenal pasti titik-titik harga yang melampau menggunakan Bollinger Bands untuk mendapatkan garis ZigZag.

  2. Mengenali corak ABCD lengkap pada garis ZigZag. Titik A, B, C dan D perlu memenuhi hubungan perkadaran tertentu.

  3. Tetapkan Stop Loss Trailing selepas membuka kedudukan untuk mengawal risiko. Gunakan Stop Loss tetap terlebih dahulu, beralih ke Stop Loss Trailing untuk mengunci beberapa keuntungan selepas mencapai tahap keuntungan tertentu.

  4. Begitu juga, mengambil keuntungan terakhir juga ditetapkan untuk mendapatkan keuntungan yang mencukupi dalam masa dan mengelakkan kerugian.

  5. Tutup kedudukan apabila harga mencapai stop loss atau mengambil keuntungan untuk menamatkan kitaran perdagangan.

III. Analisis Kelebihan

  1. Menggunakan Bollinger Bands untuk mengenal pasti garis ZigZag mengelakkan masalah melukis semula ZigZag tradisional, menjadikan isyarat perdagangan lebih boleh dipercayai.

  2. Model perdagangan corak ABCD adalah matang dan stabil dengan peluang perdagangan yang mencukupi.

  3. Tetapan stop loss dan mengambil keuntungan dua peringkat membantu mengawal risiko dengan lebih baik dan memastikan keuntungan.

  4. Reka bentuk parameter yang munasabah seperti peratusan stop loss, mengambil keuntungan dan pengaktifan pengekalan semuanya boleh disesuaikan untuk fleksibiliti.

  5. Strategi ini boleh digunakan untuk mana-mana instrumen perdagangan, termasuk forex, mata wang kripto, indeks saham, dll.

IV. Analisis Risiko

  1. Peluang perdagangan untuk corak ABCD masih terhad berbanding dengan strategi lain, tidak memastikan kekerapan yang mencukupi.

  2. Semasa pasaran berkisar, stop loss dan mengambil keuntungan mungkin diaktifkan dengan kerap. Parameter memerlukan penyesuaian seperti memperluaskan julat stop loss / keuntungan.

  3. Kecairan instrumen dagangan memerlukan perhatian. Slippage memerlukan pertimbangan untuk produk tidak cair.

  4. Strategi ini sensitif terhadap kos transaksi. Broker dan akaun dengan kadar komisen yang rendah lebih disukai.

  5. Sesetengah parameter boleh dioptimumkan lagi, seperti tahap pengaktifan untuk menghentikan kerugian dan mengambil keuntungan.

V. Arahan pengoptimuman

  1. Menggabungkan dengan penunjuk lain untuk menambah lebih banyak penapis mengelakkan beberapa isyarat palsu dan mengurangkan perdagangan yang tidak cekap.

  2. Tambah penilaian mengenai struktur pasaran tiga bahagian, hanya mengambil perdagangan di bahagian ketiga.

  3. Uji dan optimumkan modal awal untuk mencari tahap yang optimum.

  4. Melakukan analisis berjalan maju dengan data luar sampel untuk memeriksa ketahanan parameter dalam jangka panjang.

  5. Teruskan mengoptimumkan keadaan pengaktifan dan saiz slippage kehilangan hentian dan mengambil keuntungan untuk meningkatkan kecekapan.

VI. Ringkasan Strategi

Strategi ini terutamanya bergantung pada corak ABCD untuk masa dan kemasukan pasaran. Tetapan stop loss dan mengambil keuntungan dua peringkat digunakan untuk menguruskan risiko dan keuntungan. Strategi ini agak matang dan stabil tetapi kekerapan perdagangan mungkin rendah. Kita boleh mendapatkan peluang perdagangan yang lebih cekap dengan menambah penapis dan syarat. Juga penyesuaian parameter dan ukuran modal yang lebih lanjut dapat meningkatkan kestabilan keuntungan. Secara keseluruhan, ini adalah strategi dengan logika yang jelas dan mudah difahami, bernilai penyelidikan mendalam dan penerapan dalam perdagangan kuantitatif sebenar.


/*backtest
start: 2024-02-11 00:00:00
end: 2024-02-18 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// @version=4
// @author=Daveatt - BEST

// ABCD Pattern Strat

StrategyName        = "BEST ABCD Pattern Strategy (Trailing SL + TP)"
ShortStrategyName   = "BEST ABCD Strategy (Trailing)" 

strategy(title=StrategyName, shorttitle=ShortStrategyName, overlay=true )

filterBW = input(false, title="filter Bill Williams Fractals?")

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////// UTILITIES ///////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

//  ||-----------------------------------------------------------------------------------------------------||
//  ||---   Fractal Recognition Functions:  ---------------------------------------------------------------||
isRegularFractal(mode, _high, _low) =>
    ret = mode == 1 ? _high[4] < _high[3] and _high[3] < _high[2] and _high[2] > _high[1] and _high[1] > _high[0] :
     mode == -1 ? _low[4] > _low[3] and _low[3] > _low[2] and _low[2] < _low[1] and _low[1] < _low[0] : false

isBWFractal(mode, _high, _low) =>
    ret = mode == 1 ? _high[4] < _high[2] and _high[3] <= _high[2] and _high[2] >= _high[1] and _high[2] > _high[0] :
     mode == -1 ? _low[4] > _low[2] and _low[3] >= _low[2] and _low[2] <= _low[1] and _low[2] < _low[0] : false

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
////////////////////////////// ABCD PATTERN ///////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

f_abcd()=>

    _r = timeframe.period
    _g = barmerge.gaps_off
    _l = barmerge.lookahead_on

    _high = high
    _low = low

    filteredtopf = filterBW ? isRegularFractal(1, _high, _low) : isBWFractal(1, _high, _low)
    filteredbotf = filterBW ? isRegularFractal(-1, _high, _low) : isBWFractal(-1, _high, _low)

    //  ||---   ZigZag:
    istop = filteredtopf
    isbot = filteredbotf
    topcount = barssince(istop)
    botcount = barssince(isbot)

    zigzag = (istop and topcount[1] > botcount[1] ? _high[2] :
     isbot and topcount[1] < botcount[1] ? _low[2] : na)

    x = valuewhen(zigzag, zigzag, 4) 
    a = valuewhen(zigzag, zigzag, 3) 
    b = valuewhen(zigzag, zigzag, 2) 
    c = valuewhen(zigzag, zigzag, 1) 
    d = valuewhen(zigzag, zigzag, 0)

    xab = (abs(b-a)/abs(x-a))
    xad = (abs(a-d)/abs(x-a))
    abc = (abs(b-c)/abs(a-b))
    bcd = (abs(c-d)/abs(b-c))

    // ABCD Part
    _abc = abc >= 0.382 and abc <= 0.886
    _bcd = bcd >= 1.13 and bcd <= 2.618
    
    _bull_abcd = _abc and _bcd and d < c 
    _bear_abcd = _abc and _bcd and d > c

    _bull   = _bull_abcd and not _bull_abcd[1]
    _bear   = _bear_abcd and not _bear_abcd[1]

    [_bull, _bear, zigzag]

lapos_x = timenow + round(change(time)*12)

[isLong, isShort, zigzag]  = f_abcd()

plot(zigzag, title= 'ZigZag', color=color.black, offset=-2)
plotshape(isLong, style=shape.labelup, location=location.belowbar, color=color.new(color.green, 0), size=size.normal, text="ABCD", textcolor=color.white)
plotshape(isShort, style=shape.labeldown, location=location.abovebar, color=color.new(color.maroon, 0), size=size.normal, text="ABCD", textcolor=color.white)


long_entry_price    = valuewhen(isLong, close, 0)
short_entry_price   = valuewhen(isShort, close, 0)

sinceNUP = barssince(isLong)
sinceNDN = barssince(isShort)

buy_trend   = sinceNDN > sinceNUP
sell_trend  = sinceNDN < sinceNUP

change_trend = (buy_trend and sell_trend[1]) or (sell_trend and buy_trend[1])

entry_price  = buy_trend ? long_entry_price : short_entry_price

///////////////////////////////
//======[ Trailing STOP ]======//
///////////////////////////////

// use SL?
useSL = input(true, "Use stop Loss")
// Configure trail stop level with input
StopTrailPerc = input(title="Trail Loss (%)", type=input.float, minval=0.0, step=0.1, defval=3) * 0.01
// Will trigger the take profit trailing once reached
use_SL_Trigger = input(true, "Use stop Loss Trigger")
StopTrailTrigger   = input(2.0, "SL Trigger (%)",minval=0,step=0.5,type=input.float) * 0.01


StopLossPriceTrigger = 0.0
StopLossPriceTrigger := if (use_SL_Trigger)
    if buy_trend
        entry_price * (1 + StopTrailTrigger) 
    else
        entry_price * (1 - StopTrailTrigger)
else
    -1


var SL_Trigger_Long_HIT = false
SL_Trigger_Long_HIT := useSL and use_SL_Trigger and buy_trend and high >= StopLossPriceTrigger
 ? true : SL_Trigger_Long_HIT[1]


var SL_Trigger_Short_HIT = false
SL_Trigger_Short_HIT := useSL and use_SL_Trigger and sell_trend and low <= StopLossPriceTrigger
 ? true : SL_Trigger_Short_HIT[1]


display_long_SL_trigger     = useSL and buy_trend  and use_SL_Trigger 
 and SL_Trigger_Long_HIT == false and StopLossPriceTrigger != -1
display_short_SL_trigger    = useSL and sell_trend and use_SL_Trigger 
 and SL_Trigger_Short_HIT == false and StopLossPriceTrigger != -1
display_SL_trigger          = display_long_SL_trigger or display_short_SL_trigger

plot(display_SL_trigger ? StopLossPriceTrigger : na, title='SLPriceTrigger', transp=0, 
 color=color.maroon, style=plot.style_circles, linewidth=3)


// Determine trail stop loss prices
longStopPrice = 0.0, shortStopPrice = 0.0

longStopPrice := if useSL and buy_trend
    stopValue = low * (1 - StopTrailPerc)
    max(stopValue, longStopPrice[1])
else
    0

shortStopPrice := if useSL and sell_trend
    stopValue = high * (1 + StopTrailPerc)
    min(stopValue, shortStopPrice[1])
else
    999999

//////////////////////////////////////////////////////////////////////////////////////////
//*** STOP LOSS HIT CONDITIONS  ***//
//////////////////////////////////////////////////////////////////////////////////////////

cond_long_stop_loss_hit  = useSL and buy_trend and crossunder(low, longStopPrice[1]) 
 and (SL_Trigger_Long_HIT or use_SL_Trigger == false)
cond_short_stop_loss_hit = useSL and sell_trend and crossover(high, shortStopPrice[1]) 
 and (SL_Trigger_Short_HIT or use_SL_Trigger == false)


// Plot stop loss values for confirmation
plot(series=useSL and buy_trend and low >= longStopPrice 
 and (SL_Trigger_Long_HIT or use_SL_Trigger == false)
 ? longStopPrice : na,
 color=color.fuchsia, style=plot.style_cross,
 linewidth=2, title="Long Trail Stop")

plot(series=useSL and sell_trend and high <= shortStopPrice 
 and (SL_Trigger_Short_HIT or use_SL_Trigger == false)
 ? shortStopPrice : na,
 color=color.fuchsia, style=plot.style_cross,
 linewidth=2, title="Short Trail Stop")


///////////////////////////////
//======[ Take Profit ]======//
///////////////////////////////

// Use TP?
useTP = input(true, "Use take profit")
// TP trailing
ProfitTrailPerc     = input(1.0, "Trailing Profit (%)",minval=0,step=0.5,type=input.float) * 0.01

use_TP_Trigger = input(true, "Use Take Profit Trigger")
// Will trigger the take profit trailing once reached
takeProfitTrigger   = input(3.0, "Take Profit Trigger (%)",minval=0,step=0.5,type=input.float) * 0.01


// ttp := ttp>tp ? tp : ttp

takeprofitPriceTrigger = 0.0
takeprofitPriceTrigger := if (use_TP_Trigger)
    if (buy_trend)
        entry_price * (1 + takeProfitTrigger) 
    else
        entry_price * (1 - takeProfitTrigger)
else
    -1

//plot(entry_price, title='entry_price', transp=100)

var TP_Trigger_Long_HIT = false
TP_Trigger_Long_HIT := useTP and use_TP_Trigger and buy_trend and high >= takeprofitPriceTrigger
 ? true : TP_Trigger_Long_HIT[1]


var TP_Trigger_Short_HIT = false
TP_Trigger_Short_HIT := useTP and use_TP_Trigger and sell_trend and low <= takeprofitPriceTrigger
 ? true : TP_Trigger_Short_HIT[1]


display_long_TP_trigger     = useTP and buy_trend  and TP_Trigger_Long_HIT == false 
 and takeprofitPriceTrigger != -1
display_short_TP_trigger    = useTP and sell_trend and TP_Trigger_Short_HIT == false 
 and takeprofitPriceTrigger != -1
display_TP_trigger          = display_long_TP_trigger or display_short_TP_trigger


//🔷🔷🔷
// @hugo: Will display the TP trigger as long as not hit
// once the TP trigger is hit, the TP trailing will activate
plot(display_TP_trigger ? takeprofitPriceTrigger : na, title='takeprofitPriceTrigger', transp=0, color=color.orange, 
 style=plot.style_cross, linewidth=3)

longTrailTP= 0.0, shortTrailTP = 0.0

// Trailing Profit
// Start trailing once trigger is reached
longTrailTP := if useTP and buy_trend 
    tpValue = high * (1 + ProfitTrailPerc)
    max(tpValue, longTrailTP[1])
else
    0

shortTrailTP := if useTP and sell_trend
    tpValue = low * (1 - ProfitTrailPerc)
    min(tpValue, shortTrailTP[1])
else
    999999

//plot(longTrailTP, title='debug longTrailTP', transp=100)
//plot(shortTrailTP, title='debug shortTrailTP', transp=100)

//////////////////////////////////////////////////////////////////////////////////////////
//*** TRAILING TAKE PROFIT HIT CONDITIONS TO BE USED IN ALERTS  ***//
//////////////////////////////////////////////////////////////////////////////////////////


//🔷🔷🔷
// @hugo: I use crossover/crossunder for the alerts to trigger the events only once
cond_long_trail_tp_hit      = useTP and buy_trend   and crossover(high, longTrailTP[1]) 
 and (TP_Trigger_Long_HIT or use_TP_Trigger == false)
cond_short_trail_tp_hit     = useTP and sell_trend  and crossunder(low, shortTrailTP[1]) 
 and (TP_Trigger_Short_HIT or use_TP_Trigger == false)
// 🔷🔷🔷


// Plot take profits values for confirmation
// Display the trailing TP until not hit
plot(series= useTP and buy_trend and high <= longTrailTP and 
 (TP_Trigger_Long_HIT or use_TP_Trigger == false) ? longTrailTP : na,
 color=color.aqua, style=plot.style_circles,
 linewidth=2, title="Long Trail TP")

plot(series= useTP and sell_trend and low >= shortTrailTP and 
 (TP_Trigger_Short_HIT or use_TP_Trigger == false) ? shortTrailTP : na,
 color=color.aqua, style=plot.style_circles,
 linewidth=2, title="Short Trail TP")

close_long  = cond_long_trail_tp_hit or cond_long_stop_loss_hit
close_short = cond_short_trail_tp_hit or cond_short_stop_loss_hit


strategy.entry("Long", 1, when=isLong)
strategy.close("Long", when=close_long)

strategy.entry("Short", 0,  when=isShort)
strategy.close("Short", when=close_short)

if change_trend
    SL_Trigger_Long_HIT := false
    SL_Trigger_Short_HIT := false
    TP_Trigger_Long_HIT := false
    TP_Trigger_Short_HIT := false

Lebih lanjut