ストップ・ロストとテイク・プロフィート・トラッキングの最良の ABCD パターン・トレーディング戦略

作者: リン・ハーンチャオチャン,日付: 2024-02-19 11:22:48
タグ:

img

I. 戦略の概要

この戦略は"Best ABCD Pattern Strategy (Stop Loss と Take Profit Tracking) "と呼ばれる.これは明確なABCD価格パターンモデルに基づいて取引する定量戦略である.主なアイデアは,完全なABCDモデルを特定した後,ABCDパターンの方向に応じてロングまたはショートに行くこと,そしてポジションを管理するためにストップロストとプロフィートトラッキングを設定することです.

戦略の原則

  1. 極値の値点をボリンジャー帯で特定してジグザグ線を得ます

  2. ZigZag線上の完全なABCDパターンを認識する.ポイントA,B,C,Dは一定の比例関係を満たさなければならない.適格なABCDパターンを特定した後,長または短に行く.

  3. リスクを制御するために,ポジションを開いた後にトライリングストップロスを設定します.まず固定ストップロスを使用し,特定の利益レベルに達した後,いくつかの利益をロックするためにトライリングストップロスを使用します.

  4. 同様に,後継取利益も,十分な利益を時間内に確保し損失を回避するために設定されています.後継取利益も2段階で行われます.まず固定取利益,その後後継取利益.

  5. 価格がストップ・ロストに達するとポジションを閉じるか,取引サイクルを終了するために利益を取ります.

III. 利点分析

  1. ビーリング・バンドを使用してZigZag線を識別することで,伝統的なZigZagの問題を再塗りにするのを避け,取引信号をより信頼できます.

  2. ABCDパターンの取引モデルは成熟し,十分な取引機会を持つ安定しています.また,ポジションの方向性を決定することは簡単です.

  3. 2段階のストップ・ロストと収益設定は,リスクをより良く制御し,利益を確保するのに役立ちます. トレイリング機能は柔軟性を提供します.

  4. ストップ・ロスの割合,利益の引き上げ,トレーリング・アクティベーションといった合理的なパラメータ設計は,柔軟性のためにすべてカスタマイズできます

  5. この戦略は,forex,暗号通貨,株式指数など,あらゆる取引手段に使用できます.

IV リスク分析

  1. ABCDパターンの取引機会は,他の戦略と比較してまだ限られており,十分な頻度が確保されていません.

  2. レンジング市場では,ストップ・ロストとテイク・プロフィートが頻繁に起動することがあります.ストップ・ロスト/プロフィートの範囲を広げることなどのパラメータの調整が必要です.

  3. 取引手段の流動性には注意が必要です.不流動な商品のスライプは考慮する必要があります.

  4. この戦略は取引コストに敏感で,低佣金率のブローカーや口座が好ましい.

  5. いくつかのパラメータはさらに最適化できます.例えば,ストップ損失と利益を引き継ぐためのアクティベーションレベルなどです.より多くの値をテストして最適な値を見つけることができます.

V.最適化の方向性

  1. 他の指標と組み合わせてフィルターを追加することで,いくつかの誤った信号が回避され,非効率な取引が減少します.

  2. 3つのセクションの市場構造に判断を加え,第3セクションでの取引のみをします.これは勝利率を向上させることができます.

  3. 初期資本をテストし最適化して最適な水準を見つけます.大きすぎたり小さすぎたりすると,収益率が低下します.

  4. サンプル外データで前向きな分析を行い,長期的なパラメータの安定性を調べる.

  5. 効率を向上させるため,停止損失のアクティベーション条件とスライドサイズを最適化し,利益を上げ続けます. 設定の最適化は終わりません.

戦略の概要

この戦略は,主に市場タイミングとエントリのためのABCDパターンに依存している.リスクと利益を管理するために,2段階のトラッキングストップ損失と利益の設定が使用されている.この戦略は比較的成熟し安定しているが,取引頻度は低くなることがあります.フィルターと条件を追加することによってより効率的な取引機会を得ることができます.さらにパラメータ調整と資本のサイズ設定は,利益の安定性を向上させることができます.全体的に言えば,これは明確な論理と理解しやすい戦略であり,実際の定量取引で深入的な研究と適用に値します.


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

もっと