가장 좋은 ABCD 패턴 거래 전략

저자:차오장, 날짜: 2024-02-19 11:22:48
태그:

img

I. 전략 개요

이 전략은 Best ABCD Pattern Strategy (Stop Loss and Take Profit Tracking) 라고 불린다. 이것은 명확한 ABCD 가격 패턴 모델을 기반으로 거래하는 양적 전략이다. 주요 아이디어는 완전한 ABCD 모델을 식별한 후 ABCD 패턴의 방향에 따라 길거나 짧게 이동하고 포지션을 관리하기 위해 스톱 로스를 설정하고 수익 추적을 하는 것입니다.

II. 전략 원칙

  1. 지그자그 라인을 얻기 위해 볼링거 밴드를 사용하여 가격의 극한점을 식별합니다.

  2. 지그자그 선의 완전한 ABCD 패턴을 인식합니다. A, B, C 및 D 지점은 특정 비례 관계를 충족해야합니다. 적당한 ABCD 패턴을 식별 한 후 길거나 짧게 이동하십시오.

  3. 리스크를 제어하기 위해 포지션을 열고 후속 스톱 로스를 설정합니다. 먼저 고정 스톱 로스를 사용 하 여 특정 수익 수준에 도달 한 후 일부 이익을 잠금 하 고 후속 스톱 로스로 전환 합니다.

  4. 마찬가지로 후속 영업이익은 또한 충분한 수익을 확보하고 손실을 피하기 위해 설정됩니다. 후속 영업이익은 또한 두 단계로 작동합니다. 먼저 고정 영업이익, 그 다음 후속 영업이익.

  5. 가격이 마이너스 스톱 로스를 달성했을 때 포지션을 닫거나 거래 사이클을 끝내는 수익을 취합니다.

III. 이점 분석

  1. 지그자그 라인을 식별하기 위해 볼링거 밴드를 사용하면 전통적인 지그자그의 문제를 재칠하는 것을 피하고 거래 신호를 더 신뢰할 수 있습니다.

  2. ABCD 패턴 거래 모델은 충분한 거래 기회와 함께 성숙하고 안정적입니다. 또한 위치 방향을 결정하는 것이 쉽습니다.

  3. 두 단계의 후속 스톱 로스 및 수익 취득 설정은 위험을 더 잘 제어하고 수익을 확보 할 수 있습니다. 후속 기능은 유연성을 제공합니다.

  4. 합리적인 매개 변수 설계로 스톱 로스, 영업이익 및 후속 활성화 비율은 모두 유연성을 위해 사용자 정의 할 수 있습니다.

  5. 이 전략은 외환, 암호화폐, 주식 지수 등 모든 거래 수단에 사용할 수 있습니다.

IV. 위험 분석

  1. ABCD 패턴의 거래 기회는 다른 전략에 비해 여전히 제한되어 있으며 충분한 빈도를 보장하지 않습니다.

  2. 범위 시장에서 스톱 로스 및 영업이익은 자주 발생 할 수 있습니다. 스톱 로스 / 영업 범위의 확대와 같은 매개 변수는 조정되어야합니다.

  3. 거래 도구의 유동성은 주의가 필요합니다. 유동성 없는 제품에서는 미끄러짐이 고려되어야합니다.

  4. 이 전략은 거래 비용에 민감합니다. 낮은 수수료율의 중개사와 계좌가 선호됩니다.

  5. 일부 매개 변수들은 더 이상 최적화 될 수 있습니다. 예를 들어 후속 스톱 손실 및 수익을 취하기 위한 활성화 레벨과 같이. 최적의 값을 찾기 위해 더 많은 값을 테스트 할 수 있습니다.

V. 최적화 방향

  1. 더 많은 필터를 추가하기 위해 다른 지표와 결합하면 일부 잘못된 신호를 피하고 비효율적인 거래를 줄입니다.

  2. 세 부분의 시장 구조에 대한 판단을 추가하십시오. 세 번째 섹션에서 거래를만하십시오. 이것은 승률을 향상시킬 수 있습니다.

  3. 초기 자본을 테스트하고 최적화하여 최적의 수준을 찾습니다. 너무 크고 너무 작은 크기는 수익률을 손상시킵니다.

  4. 샘플 외의 데이터로 진행 분석을 수행하여 장기적으로 매개 변수의 안정성을 조사합니다.

  5. 활성화 조건과 슬라이프 크기를 최적화 하 고 효율성을 높이기 위해 수익을 취하십시오. 설정의 최적화는 결코 끝나지 않습니다.

VI. 전략 요약

이 전략은 주로 시장 타이밍 및 엔트리를 위해 ABCD 패턴에 의존합니다. 두 단계의 후속 스톱 손실 및 수익 설정은 위험과 이익을 관리하는 데 사용됩니다. 전략은 상대적으로 성숙하고 안정적이지만 거래 빈도는 낮을 수 있습니다. 필터와 조건을 추가함으로써 더 효율적인 거래 기회를 얻을 수 있습니다. 또한 추가 매개 변수 조정 및 자본 크기는 수익 안정성을 향상시킬 수 있습니다. 전반적으로 이것은 명확한 논리와 이해하기 쉬운 전략이며 실제 양적 거래에서 심층 연구와 응용을 가치가 있습니다.


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

더 많은