GitHub で見る
潜在的な参入戦略
概要
潜在的なエントリ戦略は、元の EA_PotentialEntries.mq5 エキスパート アドバイザーのロジックを複製します。最新の完成したローソク足のペアを分析し、特定の 2 つのローソク足の反転または勢いパターンが現れたときに取引を発行します。この戦略は一度に一方向 (強気または弱気) に機能し、Pattern Side パラメーターで選択できます。プロテクティブストップレベルは、分析されたローソク足ペアの極値にある元の MetaTrader ストップの配置を反映するために、エントリーごとに再計算されます。
この実装では、StockSharp の高レベルの API を使用します。これは、設定されたローソク タイプをサブスクライブし、ProcessCandle 内のストリームを処理し、BuyMarket/SellMarket でポジションをオープンし、内部で追跡されているストップ価格を突破したときに市場出口を通じて取引を閉じます。チャートにはローソク足シリーズと戦略トレードが表示され、目で見てすぐに確認できます。
データとパラメータ
| グループ |
名前 |
説明 |
| 一般 |
パターン面 |
パターン スキャンの方向: Bullish は強気の反転を検索し、Bearish は弱気の反転を検索します。 |
| 取引 |
取引高 |
すべてのエントリーに使用される成行注文のサイズ。この戦略は、新しいポジションをオープンする前に、反対のエクスポージャをフラット化します。 |
| 一般 |
キャンドルの種類 |
パターン認識に使用されるローソク足シリーズ (デフォルト: 毎時ローソク足)。 |
取引ロジック
この戦略は、最後に終了したローソク足 (C1) を前のローソク足 (C2) とともに評価します。芯と本体の寸法はすべて価格単位で計算されます。
強気モード
Pattern Side = Bullish の場合、次の設定により長いエントリがトリガーされます。
- 強気のハンマー
C1 は始値を上回って終了しますが、C2 は弱気です。
C1 の下芯は本体の少なくとも 2 倍、上芯の 3 倍以上です。
- 成行買い注文が送信され、ストップレベルは
C1 と C2 の安値の低い方に設定されます。
- 強気の逆ハンマー
C1 は強気、C2 は弱気です。
C1 の上芯は本体の少なくとも 2 倍、下芯の少なくとも 3 倍です。
- ハンマー設定と同じ命令および停止ロジックを実行します。
- 強気の勢いを築く人
C1 と C2 は両方とも強気です。
C1 の範囲は C2 の範囲より大きく、C1 の本文は C2 の本文の少なくとも 2 倍です。
- ペアの最低安値を下回るストップでロングポジションをオープンします。
弱気モード
Pattern Side = Bearish の場合、次の設定により短いエントリがトリガーされます。
- 流れ星
C1 は始値を下回って終了しますが、C2 は強気です。
C1 の上芯は本体の少なくとも 2 倍、下芯の少なくとも 3 倍です。
- 成行売り注文は、
C1 と C2 の高値を上回るストップを設定して送信されます。
- 吊るされた男
C1は弱気、C2は強気です。
C1 の下芯は本体の少なくとも 2 倍、上芯の 3 倍以上です。
- ショートポジションをオープンし、流れ星と同じストップロジックを使用します。
- 弱気の勢いを築く人
C1 と C2 は弱気です。
C1 の本文は C2 の本文より大きく、C1 の範囲は C2 の範囲の少なくとも 2 倍です。
- ショートでエントリーし、分析されたローソク足の最大高値を上回るストップを保存します。
ストップ管理とポジション処理
- 一度にアクティブになる指向性モードは 1 つだけです。取引に入る前に、この戦略は反対方向のポジションをクローズします。
- 各エントリは、ローソク足ペアの極値でのストップ価格を記録します。新しい完成したローソク足が到着するたびに、戦略は安値 (ロングの場合) または高値 (ショートの場合) が保存されたレベルに違反しているかどうかをチェックし、トリガーされた場合は成行注文でポジションをクローズします。
- オープンなポジションがない場合、保存されているストップ値はクリアされ、古いレベルが再利用されないことが保証されます。
使用上の注意
- 長い機会をスキャンするか短い機会をスキャンするかに応じて、
Bullish または Bearish モードを選択します。
- デフォルトの時間足ローソク足は、他の利用可能なローソク足データ型に置き換えることができます。
- 要求された Python ポートはまだありません。 C# 実装のみが提供されます。
- この戦略では利益目標は設定しません。出口は、ローソク足ベースのストップロジックまたは手動介入のみに依存します。
namespace StockSharp.Samples.Strategies;
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Potential Entries strategy: two-candle reversal patterns with RSI confirmation.
/// Detects bullish/bearish reversals and trades with RSI filter.
/// </summary>
public class PotentialEntriesStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
private readonly StrategyParam<int> _signalCooldownCandles;
private readonly List<ICandleMessage> _candles = new();
private int _candlesSinceTrade;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public int SignalCooldownCandles { get => _signalCooldownCandles.Value; set => _signalCooldownCandles.Value = value; }
public PotentialEntriesStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "Indicators");
_signalCooldownCandles = Param(nameof(SignalCooldownCandles), 6)
.SetGreaterThanZero()
.SetDisplay("Signal Cooldown", "Bars to wait between trades", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_candles.Clear();
_candlesSinceTrade = SignalCooldownCandles;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_candles.Clear();
_candlesSinceTrade = SignalCooldownCandles;
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;
if (_candlesSinceTrade < SignalCooldownCandles)
_candlesSinceTrade++;
_candles.Add(candle);
if (_candles.Count > 5)
_candles.RemoveAt(0);
if (_candles.Count >= 2)
{
var curr = _candles[^1];
var prev = _candles[^2];
// Bullish reversal: prev bearish, curr bullish with higher close
var bullish = prev.OpenPrice > prev.ClosePrice
&& curr.ClosePrice > curr.OpenPrice
&& curr.ClosePrice > prev.OpenPrice;
// Bearish reversal: prev bullish, curr bearish with lower close
var bearish = prev.ClosePrice > prev.OpenPrice
&& curr.OpenPrice > curr.ClosePrice
&& curr.ClosePrice < prev.OpenPrice;
if (bullish && rsiValue < 50 && Position <= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
BuyMarket();
_candlesSinceTrade = 0;
}
else if (bearish && rsiValue > 50 && Position >= 0 && _candlesSinceTrade >= SignalCooldownCandles)
{
SellMarket();
_candlesSinceTrade = 0;
}
}
}
}
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 potential_entries_strategy(Strategy):
def __init__(self):
super(potential_entries_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30)))
self._rsi_period = self.Param("RsiPeriod", 14)
self._signal_cooldown_candles = self.Param("SignalCooldownCandles", 6)
self._candles = []
self._candles_since_trade = 6
@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 SignalCooldownCandles(self):
return self._signal_cooldown_candles.Value
@SignalCooldownCandles.setter
def SignalCooldownCandles(self, value):
self._signal_cooldown_candles.Value = value
def OnReseted(self):
super(potential_entries_strategy, self).OnReseted()
self._candles.clear()
self._candles_since_trade = self.SignalCooldownCandles
def OnStarted2(self, time):
super(potential_entries_strategy, self).OnStarted2(time)
self._candles.clear()
self._candles_since_trade = self.SignalCooldownCandles
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
if self._candles_since_trade < self.SignalCooldownCandles:
self._candles_since_trade += 1
self._candles.append(candle)
if len(self._candles) > 5:
self._candles.pop(0)
if len(self._candles) >= 2:
curr = self._candles[-1]
prev = self._candles[-2]
bullish = (float(prev.OpenPrice) > float(prev.ClosePrice)
and float(curr.ClosePrice) > float(curr.OpenPrice)
and float(curr.ClosePrice) > float(prev.OpenPrice))
bearish = (float(prev.ClosePrice) > float(prev.OpenPrice)
and float(curr.OpenPrice) > float(curr.ClosePrice)
and float(curr.ClosePrice) < float(prev.OpenPrice))
if bullish and float(rsi_value) < 50 and self.Position <= 0 and self._candles_since_trade >= self.SignalCooldownCandles:
self.BuyMarket()
self._candles_since_trade = 0
elif bearish and float(rsi_value) > 50 and self.Position >= 0 and self._candles_since_trade >= self.SignalCooldownCandles:
self.SellMarket()
self._candles_since_trade = 0
def CreateClone(self):
return potential_entries_strategy()