
この戦略は,ストキャスティックRSIと価格変動率指標を使用して,多空券へのトレンド方向を識別し,座標滑動ストップ方法を使用してリスク管理を行う.
まず,戦略は長さ5のRSI指標と長さ7のストキャスティック指標を使用してストキャスティックRSIを計算します. ストキャスティックRSIのK値がD値より高い場合は看板信号,K値がD値より低い場合は下落信号になります.
次に,戦略は,価格の変動率指標EMA ROCを計算する.EMA ROCが値の半分以上または値のマイナス半分以下であるときは,価格が活発に変化していると考えられる.
ストキャスティックRSIの多空信号と価格変動率指標を組み合わせて,トレンドの方向を識別できます. ストキャスティックRSIが上昇し,価格が活発に変化するときは,多空を; ストキャスティックRSIが低下し,価格が活発に変化するときは,空白を.
最後に,この戦略は,座標滑動ストップ方式を使用してリスクを管理する. ポジションを開設した後,最高価格または最低価格を更新し続け,最高価格または最低価格から一定割合の距離をストップポイントとして使用する.
この戦略の利点は以下の通りです.
ストキャスティックRSI指標は,トレンドや超買いや超売りを効果的に識別できます.
価格変動の指標は,波動的な市場をフィルターして,偽の信号を回避します.
座標滑動ストップは,利潤を最大限に固定し,同時にリスクを制御します.
策略パラメータの最適化スペースは広く,異なる品種に対して調整することができる。
戦略はシンプルでわかりやすく,実行は簡単です.
この戦略にはいくつかのリスクがあります.
ストキャスティックRSIは偽信号を生じさせ,他の要因と組み合わせて確認する必要がある.
座標滑動停止は,夜間ギャップで打たれるほど激進的かもしれません.
ストップダメージが発動される可能性のある短期的な逆転.
戦略のパラメータは,異なる品種に対して最適化する必要があります. そうでなければ,効果が悪くなる可能性があります.
取引コストは戦略の収益性に影響し,合理的な取引頻度を考えることが必要である.
この戦略は,以下の点で最適化できます.
ストカスティックRSIパラメータを最適化して偽信号率を下げる.異なるK値とD値のパラメータをテストすることができる.
価格変動指数パラメータを最適化し,フィルタリング効果を向上させる.異なるウィンドウ期と変動の値をテストすることができる.
トレンド判断指標と組み合わせて,反転ストップを避ける.例えば,移動平均などの指標を追加する.
ストップレスを最適化し,被套リスクを低減する.異なるストップレスをテストすることができる.
ポジション数管理を追加し,単一のリスクを制御する.例えば,固定ストップ損失額,または口座残高に応じてポジションを動的に調整する.
異なる品種のパラメータをテストし,適応性を高めます.複数の市場で複数の時間周期で検証することを好みます.
この戦略の全体的な考え方は明確でシンプルで,トレンドの方向を識別するためにStochastic 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)