ホーム
/
戦略のサンプル
GitHub で見る
RSI Levels戦略
概要
RSI Levels戦略 は、MetaTrader 5の「RSI Levels」エキスパートアドバイザーを直接移植したものです。選択した時間軸で単一シンボルを監視し、Relative Strength Index(RSI)が設定可能な買われ過ぎ/売られ過ぎしきい値をクロスしたときに動作します。戦略は、RSIが極端なゾーンに入った後に市場が平均回帰すると仮定します。指標が売られ過ぎ水準を下回るとロングポジションを開始し、買われ過ぎ水準を上回るとショートポジションを開きます。一度に保持するポジションは1つだけで、新規エントリー前に反対エクスポージャーを閉じます。
取引ロジック
RSI計算: RSIは設定可能な期間で作業時間軸上に計算されます。シグナル評価前に現在バーが確定している必要があります。
ロングエントリー: 現在のRSIが売られ過ぎ水準を下回って閉じ、前回RSIがその水準を上回っていた場合に発動します。ショートポジションがあれば即座に閉じ、なければリスクベースのポジションサイズで新しいロングを開きます。
ショートエントリー: 現在のRSIが買われ過ぎ水準を上回って閉じ、前回RSIがその水準を下回っていた場合に発動します。既存ロングエクスポージャーを先に閉じ、その後新しいショートを作成します。
ストップロス: エントリー価格からシンボルポイントで設定可能な距離に固定ストップを置きます。ゼロに設定すると無効です。
テイクプロフィット: エントリー価格からシンボルポイントで設定可能な距離に固定テイクプロフィットを置きます。ゼロの場合は無効です。
ポジション管理: 一度に開けるポジションは1つだけです。ポジションが閉じると内部状態をリセットし、次のシグナルをクリーンな状態から始めます。
ポジションサイズ
ポジションサイズは設定されたRisk % per Trade から計算されます。アルゴリズムはポートフォリオエクイティにリスク率を掛け、リスク資本をストップ距離の金額価値(ストップポイント x ステップ価格)で割ります。得られた数量は取引可能な最も近いロットステップへ切り下げられ、銘柄が提供する最小/最大数量で制限されます。必要な市場情報(price stepまたはstep price)がない場合、戦略は警告をログに記録し、利用可能な最小数量へフォールバックします。
パラメーター
パラメーター
既定値
説明
CandleType
1時間時間軸
ローソク足購読とRSI計算に使う時間軸。
RsiPeriod
14
RSI指標の期間数。
OverboughtLevel
70
買われ過ぎゾーンを定義するRSIしきい値。
OversoldLevel
30
売られ過ぎゾーンを定義するRSIしきい値。
RiskPercent
2
各取引でリスクにさらすポートフォリオエクイティの割合。
StopLossPoints
500
シンボルポイントで表すストップロス距離。ゼロで無効。
TakeProfitPoints
1000
シンボルポイントで表すテイクプロフィット距離。ゼロで無効。
実用メモ
正確なリスクサイズ計算には、銘柄にPriceStep、StepPrice、MinVolume、VolumeStepが設定されている必要があります。欠けている場合は保守的な既定値を使い、警告をログに記録します。
ロジックはSubscribeCandlesとBindを使って指標値を取得し、手動でデータを取得しません。これは高レベルAPIガイドラインに一致します。
ストップと目標はローソク足データで評価されます。スリッページやギャップにより、意図した価格から離れて約定する場合があります。
システムはローソク足確定時のみ反応するため、M15、H1、H4などの時間軸に適しています。低い時間軸ではノイズ削減のため追加フィルターが必要になる場合があります。
使用方法
戦略を希望する銘柄とポートフォリオへ接続します。
銘柄のボラティリティに合わせてRSIしきい値とリスク制御を調整します。
戦略を開始し、シンボル情報不足に関する警告をログで監視します。
取引結果を確認し、パフォーマンスに応じてストップ/テイクプロフィット距離またはRSI水準を微調整します。
このStockSharp実装は、標準の戦略パラメーターで設定とリスク管理を公開しながら、元のMetaTrader動作を再現します。
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// RSI Levels strategy: RSI oversold/overbought mean reversion.
/// Buys when RSI < 35. Sells when RSI > 65.
/// </summary>
public class RsiLevelsStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int RsiPeriod
{
get => _rsiPeriod.Value;
set => _rsiPeriod.Value = value;
}
public RsiLevelsStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(rsi, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal rsi)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (rsi < 30m && Position <= 0)
{
BuyMarket();
}
else if (rsi > 70m && Position >= 0)
{
SellMarket();
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class rsi_levels_strategy(Strategy):
def __init__(self):
super(rsi_levels_strategy, self).__init__()
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI period", "Indicators")
self._rsi = None
@property
def rsi_period(self):
return self._rsi_period.Value
def OnReseted(self):
super(rsi_levels_strategy, self).OnReseted()
self._rsi = None
def OnStarted2(self, time):
super(rsi_levels_strategy, self).OnStarted2(time)
self._rsi = RelativeStrengthIndex()
self._rsi.Length = self.rsi_period
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromHours(1)))
subscription.Bind(self._rsi, self._process_candle)
subscription.Start()
def _process_candle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
if not self._rsi.IsFormed:
return
rsi = float(rsi_value)
if rsi < 30.0 and self.Position <= 0:
self.BuyMarket()
elif rsi > 70.0 and self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return rsi_levels_strategy()