レンジブレークスルー 双動平均フィルタリング戦略

作者: リン・ハーンチャオチャン, 日付: 2023年11月27日 17:03:08
タグ:

img

概要

これは,トレンド判断のために移動平均値とボリンジャー帯を使用し,ブレイクアウトフィルタリングとストップ損失原則と組み合わせた戦略である.トレンドが変化するときにタイミングでシグナルをキャプチャし,ダブル移動平均値フィルタリングを通じて誤ったシグナルを削減し,ストップ損失を設定することでリスクを制御することができます.

戦略原則

戦略は以下の主要な部分で構成されています.

  1. 傾向判断: MACD を使って価格傾向を判断し,上昇傾向と下落傾向を区別します.

  2. レンジフィルタリング:ボリンジャー帯を使用して価格変動範囲を判断し,範囲を突破しない信号をフィルタリングします.

  3. 2つの移動平均の確認: 速いEMAと遅いEMAは,トレンド信号の確認のために2つの移動平均を形成する. 速いEMA>遅いEMAのみで購入信号が生成される.

  4. ストップ・ロスのメカニズム:ストップ・ロスのポイントを設定する.価格が不利な方向にストップ・ロスのポイントを突破するとポジションを閉じる.

入力信号の論理は

  1. MACDは上昇傾向を示している
  2. 価格がボリンジャー帯の上部レールを突破する
  3. 低速EMAより速いEMAが高い

3つの条件が同時に満たされると,買い信号が生成されます.

閉店ポジションは2種類あります.取利益とストップ損失です.取利益ポイントは,入場価格を一定の割合で倍し,ストップ損失ポイントは,入場価格を一定の割合で倍します.価格がいずれかのポイントを突破すると,ポジションを閉じる.

利点分析

この戦略の利点は次のとおりです.

  1. トレンドの変化を素早く把握できる 追跡バックが少ない
  2. 信号の質を向上させるため,二重移動平均値でフィルタリングすることで 誤った信号を減らす.
  3. ストップ損失メカニズムは,単一の損失を効果的に制御します.
  4. 適正な状態に調整できる大きなパラメータ最適化空間

リスク分析

この戦略にはいくつかのリスクもあります:

  1. 横向市場で発生する誤った信号は損失につながる可能性があります.
  2. ストップ損失の設定が正しくない場合,不必要な損失を引き起こす可能性があります.
  3. 不適切なパラメータは 戦略の不良の結果をもたらす可能性があります

これらのリスクに対処するために,パラメータを調整し,ストップロスのポジションを設定して戦略を最適化することができます.

オプティマイゼーションの方向性

戦略は以下の側面で最適化できます.

  1. 最適なパラメータの組み合わせを見つけるために 移動平均の長さを調整します
  2. トレイリング・ストップ・ロース,オシレーティング・ストップ・ロースなど,さまざまなストップ・ロース・メソッドをテストする.
  3. 最適な設定を見つけるために MACD パラメータをテストします.
  4. 自動パラメータ最適化のために機械学習を使用します
  5. フィルター信号に追加条件を追加します

異なるパラメータ設定をテストし,リターンとシャープ比率を評価することで,戦略の最適な状態を見つけることができます.

結論

この戦略は,トレンド判断,レンジフィルタリング,ダブル移動平均確認,ストップ損失のアイデアを使用する定量戦略です.トレンド方向を効果的に決定し,利益最大化とリスク管理のバランスをとることができます.パラメータ最適化,機械学習,その他の手段を通じて,戦略はより良い結果を達成するために改善の余地があります.


/*backtest
start: 2022-11-20 00:00:00
end: 2023-11-26 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy(title="Range Filter Buy and Sell Strategies", shorttitle="Range Filter Strategies", overlay=true,pyramiding = 5)

// Original Script > @DonovanWall
// Adapted Version > @guikroth
// 
// Updated PineScript to version 5
// Republished by > @tvenn
// Strategizing by > @RonLeigh
//////////////////////////////////////////////////////////////////////////
// Settings for 5min chart, BTCUSDC. For Other coin, change the parameters
//////////////////////////////////////////////////////////////////////////



SS = input.bool(false,"Percentage Take Profit Stop Loss")


longProfitPerc = input.float(title='LongProfit(%)', minval=0.0, step=0.1, defval=1.5) * 0.01

shortProfitPerc = input.float(title='ShortProfit(%)', minval=0.0, step=0.1, defval=1.5) * 0.01


longLossPerc = input.float(title='LongStop(%)', minval=0.0, step=0.1, defval=1.5) * 0.01

shortLossPerc = input.float(title='ShortStop(%)', minval=0.0, step=0.1, defval=1.5) * 0.01


// Color variables
upColor   = color.white
midColor  = #90bff9
downColor = color.blue

// Source
src = input(defval=close, title="Source")

// Sampling Period
// Settings for 5min chart, BTCUSDC. For Other coin, change the paremeters
per = input.int(defval=100, minval=1, title="Sampling Period")

// Range Multiplier
mult = input.float(defval=3.0, minval=0.1, title="Range Multiplier")

// Smooth Average Range
smoothrng(x, t, m) =>
    wper = t * 2 - 1
    avrng = ta.ema(math.abs(x - x[1]), t)
    smoothrng = ta.ema(avrng, wper) * m
    smoothrng
smrng = smoothrng(src, per, mult)

// Range Filter
rngfilt(x, r) =>
    rngfilt = x
    rngfilt := x > nz(rngfilt[1]) ? x - r < nz(rngfilt[1]) ? nz(rngfilt[1]) : x - r : 
       x + r > nz(rngfilt[1]) ? nz(rngfilt[1]) : x + r
    rngfilt
filt = rngfilt(src, smrng)

// Filter Direction
upward = 0.0
upward := filt > filt[1] ? nz(upward[1]) + 1 : filt < filt[1] ? 0 : nz(upward[1])
downward = 0.0
downward := filt < filt[1] ? nz(downward[1]) + 1 : filt > filt[1] ? 0 : nz(downward[1])

// Target Bands
hband = filt + smrng
lband = filt - smrng

// Colors
filtcolor = upward > 0 ? upColor : downward > 0 ? downColor : midColor
barcolor = src > filt and src > src[1] and upward > 0 ? upColor :
   src > filt and src < src[1] and upward > 0 ? upColor : 
   src < filt and src < src[1] and downward > 0 ? downColor : 
   src < filt and src > src[1] and downward > 0 ? downColor : midColor

filtplot = plot(filt, color=filtcolor, linewidth=2, title="Range Filter")

// Target
hbandplot = plot(hband, color=color.new(upColor, 70), title="High Target")
lbandplot = plot(lband, color=color.new(downColor, 70), title="Low Target")

// Fills
fill(hbandplot, filtplot, color=color.new(upColor, 90), title="High Target Range")
fill(lbandplot, filtplot, color=color.new(downColor, 90), title="Low Target Range")

// Bar Color
barcolor(barcolor)

// Break Outs
longCond = bool(na)
shortCond = bool(na)
longCond := src > filt and src > src[1] and upward > 0 or 
   src > filt and src < src[1] and upward > 0
shortCond := src < filt and src < src[1] and downward > 0 or 
   src < filt and src > src[1] and downward > 0

CondIni = 0
CondIni := longCond ? 1 : shortCond ? -1 : CondIni[1]
longCondition = longCond and CondIni[1] == -1
shortCondition = shortCond and CondIni[1] == 1



// alertcondition(longCondition, title="Buy alert on Range Filter", message="Buy alert on Range Filter")
// alertcondition(shortCondition, title="Sell alert on Range Filter", message="Sell alert on Range Filter")
// alertcondition(longCondition or shortCondition, title="Buy and Sell alert on Range Filter", message="Buy and Sell alert on Range Filter")


////////////// 副

sensitivity = input(150, title='Sensitivity')
fastLength = input(20, title='FastEMA Length')
slowLength = input(40, title='SlowEMA Length')
channelLength = input(20, title='BB Channel Length')
multt = input(2.0, title='BB Stdev Multiplier')

DEAD_ZONE = nz(ta.rma(ta.tr(true), 100)) * 3.7

calc_macd(source, fastLength, slowLength) =>
    fastMA = ta.ema(source, fastLength)
    slowMA = ta.ema(source, slowLength)
    fastMA - slowMA

calc_BBUpper(source, length, multt) =>
    basis = ta.sma(source, length)
    dev = multt * ta.stdev(source, length)
    basis + dev

calc_BBLower(source, length, multt) =>
    basis = ta.sma(source, length)
    dev = multt * ta.stdev(source, length)
    basis - dev

t1 = (calc_macd(close, fastLength, slowLength) - calc_macd(close[1], fastLength, slowLength)) * sensitivity

e1 = calc_BBUpper(close, channelLength, multt) - calc_BBLower(close, channelLength, multt)

trendUp = t1 >= 0 ? t1 : 0
trendDown = t1 < 0 ? -1 * t1 : 0

duoad = trendUp > 0 and trendUp > e1

kongad = trendDown > 0 and trendDown > e1



duo =  longCondition and duoad

kong = shortCondition and kongad


//Alerts
plotshape(longCondition  and trendUp > e1 and  trendUp > 0 , title="Buy Signal", text="Buy", textcolor=color.white, style=shape.labelup, size=size.small, location=location.belowbar, color=color.new(#aaaaaa, 20))
plotshape(shortCondition  and trendDown > e1 and  trendDown > 0 , title="Sell Signal", text="Sell", textcolor=color.white, style=shape.labeldown, size=size.small, location=location.abovebar, color=color.new(downColor, 20))




if  longCondition and trendUp > e1 and  trendUp > 0 
    strategy.entry('Long',strategy.long, comment = "buy" )

if  shortCondition and trendDown > e1 and  trendDown > 0 
    strategy.entry('Short',strategy.short, comment = "sell" )




longlimtPrice  = strategy.position_avg_price * (1 + longProfitPerc)
shortlimtPrice = strategy.position_avg_price * (1 - shortProfitPerc)
   
longStopPrice  = strategy.position_avg_price * (1 - longLossPerc)
shortStopPrice = strategy.position_avg_price * (1 + shortLossPerc)



if (strategy.position_size > 0)  and SS == true
    
    strategy.exit(id="Long",comment_profit = "Profit",comment_loss = "StopLoss", stop=longStopPrice,limit = longlimtPrice)
    

if (strategy.position_size < 0)  and SS == true
    
    strategy.exit(id="Short",comment_profit = "Profit",comment_loss = "StopLoss", stop=shortStopPrice,limit = shortlimtPrice)


もっと