GitHub で見る
ああ、HM RSI 戦略
概要
この戦略は、MetaTrader エキスパート Expert_AH_HM_RSI の StockSharp 移植です。ハンマーまたはハンギングマンのローソク足パターンを探し、取引前に相対強度指数 (RSI) からの確認シグナルを必要とします。このアプローチは、新しいシグナルが現れたときにポジションを反転するというリスク管理哲学を含む、オリジナルの Expert Advisor を反映しています。
取引ロジック
- トレンド フィルター – 短い単純移動平均 (デフォルトの長さ 2) を使用して、市場が微下降トレンドにあるか上昇トレンドにあるかを判断します。
- ローソク足パターン – この戦略は、最後に完了したローソク足を分析します。
- ハンマーは、実体がレンジの上位 3 分の 1 に位置し、ローソク足のギャップが前のバーよりも低く、ローソク足の中点が移動平均トレンドを下回っているときに検出されます。
- ぶら下がっている男は、本体が上位 3 分の 1 に位置し、ローソク足のギャップが前のバーより高く、ローソク足の中点が移動平均トレンドより上にある場合に検出されます。
- RSI フィルター –
- ロングトレードでは、RSI が設定可能なハンマーしきい値 (デフォルトは 40) を下回る必要があります。
- ショートトレードでは、RSI がハンギングマンのしきい値 (デフォルト 60) を超える必要があります。
- 取引執行 – 有効なシグナルでは、ストラテジーは
Volume + |Position| でエントリーするため、オープンポジションは反対のセットアップが到着するとすぐに反転されます。
- Exit ルール – RSI が設定可能な下限 (デフォルト 30) または上限 (デフォルト 70) の境界を逆方向に横切ると、ポジションは平坦化され、元のコードの EXIT 投票が複製されます。
インジケーター
- RelativeStrengthIndex (デフォルトの長さは 33)。
- SimpleMovingAverage (デフォルトでは長さ 2) がローソク足の終値に適用されます。
パラメーター
| 名前 |
説明 |
デフォルト |
Volume |
エントリーに使用される注文サイズ。 |
1 |
RsiPeriod |
RSI のルックバック期間。 |
33 |
MaPeriod |
トレンドフィルターの移動平均期間。 |
2 |
HammerRsiThreshold |
ハンマーロングエントリーを可能にする最大 RSI 値。 |
40 |
HangingManRsiThreshold |
ハンギングマンショートエントリーを許可する最小値 RSI 。 |
60 |
LowerExitLevel |
RSI 境界は、上向きクロス後にショートを閉じるために使用されます。 |
30 |
UpperExitLevel |
RSI 境界は、下降クロス後にロングを閉じるために使用されます。 |
70 |
CandleType |
戦略によって処理されるタイムフレーム。 |
1 hour キャンドル |
すべてのパラメータは、StockSharp パラメータ UI を介して最適化できます。
使用上の注意
- このロジックは完成したキャンドルに対してのみ機能します。選択した時間枠とデータ フィードで完全なバーが生成されていることを確認します。
- 反転ロジックは常に
Volume + |Position| をトレードするため、ポジションは反対のシグナルで瞬時に方向を反転し、エキスパートアドバイザーと一致します。
- 組み込みのリスク管理を起動時に一度開始します (
StartProtection() は OnStarted で呼び出されます)。
ファイル
CS/AhHmRsiStrategy.cs – 戦略の実装。
README.md – 英語のドキュメント。
README_zh.md – 中国語のドキュメント。
README_ru.md – ロシア語のドキュメント。
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Hammer/Hanging Man + RSI strategy.
/// Buys on hammer with low RSI, sells on hanging man with high RSI.
/// </summary>
public class AhHmRsiStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<decimal> _rsiLow;
private readonly StrategyParam<decimal> _rsiHigh;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public decimal RsiLow { get => _rsiLow.Value; set => _rsiLow.Value = value; }
public decimal RsiHigh { get => _rsiHigh.Value; set => _rsiHigh.Value = value; }
public AhHmRsiStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "Indicators");
_rsiLow = Param(nameof(RsiLow), 40m)
.SetDisplay("RSI Low", "RSI oversold threshold for buy", "Signals");
_rsiHigh = Param(nameof(RsiHigh), 60m)
.SetDisplay("RSI High", "RSI overbought threshold for sell", "Signals");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(rsi, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal rsiValue)
{
if (candle.State != CandleStates.Finished) return;
var body = Math.Abs(candle.ClosePrice - candle.OpenPrice);
var range = candle.HighPrice - candle.LowPrice;
if (range <= 0 || body <= 0) return;
var upperShadow = candle.HighPrice - Math.Max(candle.OpenPrice, candle.ClosePrice);
var lowerShadow = Math.Min(candle.OpenPrice, candle.ClosePrice) - candle.LowPrice;
var isHammer = lowerShadow > body * 2 && upperShadow < body;
var isHangingMan = upperShadow > body * 2 && lowerShadow < body;
if (isHammer && rsiValue < RsiLow && Position <= 0)
BuyMarket();
else if (isHangingMan && rsiValue > RsiHigh && 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 ah_hm_rsi_strategy(Strategy):
def __init__(self):
super(ah_hm_rsi_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5)))
self._rsi_period = self.Param("RsiPeriod", 14)
self._rsi_low = self.Param("RsiLow", 40.0)
self._rsi_high = self.Param("RsiHigh", 60.0)
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def RsiPeriod(self):
return self._rsi_period.Value
@RsiPeriod.setter
def RsiPeriod(self, value):
self._rsi_period.Value = value
@property
def RsiLow(self):
return self._rsi_low.Value
@RsiLow.setter
def RsiLow(self, value):
self._rsi_low.Value = value
@property
def RsiHigh(self):
return self._rsi_high.Value
@RsiHigh.setter
def RsiHigh(self, value):
self._rsi_high.Value = value
def OnStarted2(self, time):
super(ah_hm_rsi_strategy, self).OnStarted2(time)
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(rsi, self._process_candle).Start()
def _process_candle(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
rsi_val = float(rsi_value)
body = abs(float(candle.ClosePrice) - float(candle.OpenPrice))
rng = float(candle.HighPrice) - float(candle.LowPrice)
if rng <= 0 or body <= 0:
return
upper_shadow = float(candle.HighPrice) - max(float(candle.OpenPrice), float(candle.ClosePrice))
lower_shadow = min(float(candle.OpenPrice), float(candle.ClosePrice)) - float(candle.LowPrice)
is_hammer = lower_shadow > body * 2 and upper_shadow < body
is_hanging_man = upper_shadow > body * 2 and lower_shadow < body
if is_hammer and rsi_val < self.RsiLow and self.Position <= 0:
self.BuyMarket()
elif is_hanging_man and rsi_val > self.RsiHigh and self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return ah_hm_rsi_strategy()