スライディングストップ損失戦略を調整する

作者: リン・ハーンチャオチャン, 日付: 2023年11月2日 16:28:55
タグ:

img

概要

この戦略は,ストカスティックRSIと価格変動率指標を使用して,エントリー傾向の方向性を特定し,リスク管理のためにスライディングストップロスを調整します.

戦略の論理

まず,ストーカスティックRSIはRSIインジケーターを長さ5で,ストーカスティックインジケーターを長さ7で計算します.ストーカスティックRSIK値がD値以上であれば,それは上昇信号です.K値がD以下であれば,それは下落信号です.

第2に,戦略は価格変動率指標EMA ROCを計算する.EMA ROCが値の半分以上または値のマイナス半分以下である場合,活動的な価格動きを特定する.

ストコストティックRSIのシグナルと価格変動率を組み合わせて,トレンド方向を特定します.ストコストティックRSIが上昇し,価格が積極的に動いているとき,ロングに行く.ストコストティックRSIが下落し,価格が積極的に動いているとき,ショートに行く.

最後に,この戦略はリスク管理のために調整滑りストップロスを使用します. ポジションを開いた後,最高/最低価格をリフレッシュし続けており,最高/最低価格からの一定の百分比距離をストップロスのレベルとして使用します.

利点分析

この戦略の利点は

  1. ストカスティックRSI指標は,トレンドや過買い/過売状況を効果的に特定します.

  2. 価格の変動率は 誤った信号を避けるために 市場範囲をフィルタリングします

  3. 調整されたスライディングストップロスはリスクを制御しながら 最大限の利益を確保できます

  4. この戦略には 異なる製品に基づくパラメータ調整のための 広い最適化空間があります

  5. 戦略の論理は シンプルで明快で 分かりやすく実行できます

リスク分析

この戦略のリスクは

  1. ストカスティックRSIは誤った信号を生成し,他の要因で確認する必要があります.

  2. 座標滑りストップ損失は 攻撃的すぎるかもしれないし 一晩でギャップで停止されるかもしれない

  3. 短期的な逆転がストップロスを引き起こす可能性があります.

  4. パラメータは異なる製品に最適化する必要があります. そうでなければパフォーマンスが悪い可能性があります.

  5. 取引コストは戦略の収益性に影響し 合理的な取引頻度が必要です

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

この戦略は,次の側面においてさらに最適化することができる.

  1. 誤った信号を減らすためにストカスティックRSIパラメータを最適化します.

  2. フィルタリング効果を改善するために,変化パラメータの価格率を最適化します. 異なる長さと値をテストすることができます.

  3. トレンドインジケーターを追加して 逆転が止まらないようにします 例えば移動平均値です

  4. ストップロスの割合を最適化して,閉じ込められるリスクを減らす. 異なるストップロスの幅をテストすることができます.

  5. 単一の取引リスクを制御するためにポジションサイズ管理を追加します. 固定ストップ損失額など,またはアカウントの資本に基づいてポジションサイズを動的に調整します.

  6. 適応性を向上させるために,異なる製品でパラメータをテストし,複数の市場と時間枠で検証します.

概要

ストーカスティックRSIでトレンド方向を特定し,価格変動率のシグナルをフィルタリングすることで,中期・長期間のトレンドを効果的に把握できる.利益のスライディングストップロスのロックを調整し,リスクを制御する.さらなる最適化により,この戦略は戦略に従う非常に実践的なトレンドになり得る.


/*backtest
start: 2023-10-02 00:00:00
end: 2023-11-01 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("Sto2", overlay=false, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.0)

/////////////// Time Frame ///////////////
testStartYear = input(2017, "Backtest Start Year") 
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0)

testStopYear = input(2019, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0)

testPeriod() => true
    
///////////// Stochastic calc /////////////
smoothK = input(1, minval=1)
smoothD = input(7, minval=1)
lengthRSI = input(5, minval=1)
lengthStoch = input(7, minval=1)
src = input(close, title="RSI Source")

up = sma(max(change(src), 0), lengthRSI) 
down = sma(-min(change(src), 0), lengthRSI)
rsi1 = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))

k = sma(stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d = sma(k, smoothD)

///////////// Rate Of Change ///////////// 
source = close, roclength = input(14, minval=1), pcntChange = input(2, minval=1)
roc = 100 * (source - source[roclength]) / source[roclength]
emaroc = ema(roc, roclength / 2)
isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2))

/////////////// STRATEGY ///////////////
long = k > d and isMoving()
short = k < d and isMoving()

last_long = 0.0
last_short = 0.0
last_long := long ? time : nz(last_long[1])
last_short := short ? time : nz(last_short[1])

long_signal = crossover(last_long, last_short)
short_signal = crossover(last_short, last_long)

last_open_long_signal = 0.0
last_open_short_signal = 0.0
last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1])
last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1])

last_long_signal = 0.0
last_short_signal = 0.0
last_long_signal := long_signal ? time : nz(last_long_signal[1])
last_short_signal := short_signal ? time : nz(last_short_signal[1])

in_long_signal = last_long_signal > last_short_signal
in_short_signal = last_short_signal > last_long_signal

last_high = 0.0
last_low = 0.0
last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])
sl_inp = input(2.0, title='Stop Loss %') / 100
tp_inp = input(9.0, title='Take Profit %') / 100 
 
take_level_l = strategy.position_avg_price * (1 + tp_inp)
take_level_s = strategy.position_avg_price * (1 - tp_inp) 

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) // LONG SL
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) // SHORT SL

slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na
slShort = strategy.position_avg_price * (1 + sl_inp)
long_sl = in_long_signal ? slLong : na
short_sl = in_short_signal ? slShort : na

// Strategy
if testPeriod()
    strategy.entry("Long Entry",  strategy.long, when=long)
    strategy.entry("Short Entry", strategy.short, when=short)
    strategy.exit("Long Ex", "Long Entry", stop=long_sl, limit=take_level_l, when=since_longEntry > 0)
    strategy.exit("Short Ex", "Short Entry", stop=short_sl, limit=take_level_s, when=since_shortEntry > 0)
    
///////////// Plotting /////////////
bgcolor(isMoving() ? long ? color.green : short ? color.red : na : color.white, transp=80)
p1 = plot(k, color=color.gray, linewidth=0)
p2 = plot(d, color=color.gray, linewidth=0)
h0 = hline(100)
h1 = hline(50)
h3 = hline(0)
fill(p1, p2, color = k > d ? color.lime : color.red, transp=70)

もっと