GitHub で見る

Exp KWAN NRP戦略

概要

Exp KWAN NRP戦略は、確率的オシレーター、相対強度指数、モメンタムインジケーターを単一の比率に組み合わせることで元のMetaTraderエキスパートアドバイザーを再現します。この比率は設定可能な移動平均線で平滑化され、平滑化された線の傾きがポジションを開く・閉じるタイミングを決定します。このアプローチはあらゆる銘柄や時間軸で機能し、モメンタムが転換するときの方向性取引向けに設計されています。

取引ロジック

  1. 確率的な%Dラインの値にRSI値を掛け、モメンタムの読み取り値で割ることでKWAN比率を構築します。
  2. 選択した移動平均メソッド(シンプル、指数、平滑化、または加重)で比率を平滑化します。
  3. 設定可能なシグナルバーオフセットで平滑化された線の傾きを評価します。
  4. 線が上向きに転じたときにロングポジションを建て、ショートポジションを閉じます。線が下向きに転じたときにショートポジションを建て、ロングポジションを閉じます。
  5. オプションのストップロスとテイクプロフィット保護は、価格ステップで測定された事前定義された価格移動後にポジションを自動的に閉じることができます。

シグナル

  • ロングエントリー: シグナルバーの平滑化されたKWAN値が前のバーと比較して上昇し、ロングエントリーが有効な場合。
  • ロングエグジット: ロングポジションがオープンの間に平滑化されたKWAN値が下向きに転じ、ロングエグジットが有効な場合。
  • ショートエントリー: シグナルバーの平滑化されたKWAN値が前のバーと比較して下落し、ショートエントリーが有効な場合。
  • ショートエグジット: ショートポジションがオープンの間に平滑化されたKWAN値が上向きに転じ、ショートエグジットが有効な場合。

リスク管理

  • 基本注文サイズを制御するために戦略のVolumeプロパティを設定します。ポジションの反転は新しいポジションを開く前に自動的に反対のポジションを閉じます。
  • UseProtectionを有効にして、インストゥルメントの価格ステップで測定されたストップロスとテイクプロフィットレベルを適用します。両方の保護を一緒にまたは別々に使用できます。
  • 戦略はCandleTypeで定義されたキャンドルをサブスクライブし、完成したキャンドルのクローズ時に取引します。

パラメーター

名前 説明 デフォルト
CandleType インジケーター計算とシグナル評価に使用される時間軸。 1時間足キャンドル
KPeriod 確率的%Kラインの期間。 5
DPeriod 確率的%Dラインの期間。 3
SlowingPeriod 確率的%Kラインに適用される追加平滑化。 3
RsiPeriod 相対強度指数の期間。 14
MomentumPeriod モメンタムインジケーターの期間。 14
SmoothingMethod KWAN比率に適用される移動平均タイプ(Simple、Exponential、Smoothed、Weighted)。 Simple
SmoothingLength 平滑化移動平均の長さ。 3
SignalBar 傾きを評価するために使用するバーの数(0 = 現在の閉じたバー)。 1
EnableBuyEntries 強気シグナルでロングポジションを開くことを許可する。 true
EnableSellEntries 弱気シグナルでショートポジションを開くことを許可する。 true
EnableBuyExits 弱気シグナルが現れたときにロングポジションを閉じることを許可する。 true
EnableSellExits 強気シグナルが現れたときにショートポジションを閉じることを許可する。 true
UseProtection ストップロスとテイクプロフィット保護を有効にする。 true
StopLossSteps 価格ステップで表されるストップロス距離。 1000
TakeProfitSteps 価格ステップで表されるテイクプロフィット距離。 2000

使用上の注意

  • モメンタムインジケーターがゼロになるとKWAN比率が不安定になることがあります。戦略はゼロ除算を避けるためにそれらのバーのシグナルを自動的にスキップします。
  • SignalBarパラメーターにより、遅れた確認が必要な場合にシグナルを歴史的なバーに合わせることができます。
  • プロダクションでの取引に必要な場合は、ブローカーレベルのリスク管理や追加フィルターと組み合わせてください。
namespace StockSharp.Samples.Strategies;

using System;

using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Strategy replicating the Exp KWAN NRP expert advisor by combining RSI and Momentum signals.
/// Enters long when RSI crosses above 50 and momentum is positive,
/// enters short when RSI crosses below 50 and momentum is negative.
/// </summary>
public class ExpKwanNrpStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiPeriod;
	private readonly StrategyParam<int> _momentumPeriod;

	private decimal _prevRsi;
	private decimal _prevMom;
	private bool _initialized;

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public int RsiPeriod
	{
		get => _rsiPeriod.Value;
		set => _rsiPeriod.Value = value;
	}

	public int MomentumPeriod
	{
		get => _momentumPeriod.Value;
		set => _momentumPeriod.Value = value;
	}

	public ExpKwanNrpStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe for calculations", "General");

		_rsiPeriod = Param(nameof(RsiPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("RSI Period", "RSI length", "Indicators");

		_momentumPeriod = Param(nameof(MomentumPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("Momentum Period", "Momentum length", "Indicators");
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevRsi = 0m;
		_prevMom = 0m;
		_initialized = false;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_prevRsi = 0;
		_prevMom = 0;
		_initialized = false;

		var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
		var momentum = new Momentum { Length = MomentumPeriod };

		var subscription = SubscribeCandles(CandleType);

		subscription
			.Bind(rsi, momentum, (ICandleMessage candle, decimal rsiValue, decimal momValue) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				if (!_initialized)
				{
					_prevRsi = rsiValue;
					_prevMom = momValue;
					_initialized = true;
					return;
				}

				var rsiUp = rsiValue > _prevRsi;
				var rsiDown = rsiValue < _prevRsi;
				var momUp = momValue > _prevMom;
				var momDown = momValue < _prevMom;

				// Buy when both RSI and Momentum are turning up
				if (rsiUp && momUp && Position <= 0)
				{
					BuyMarket();
				}
				// Sell when both RSI and Momentum are turning down
				else if (rsiDown && momDown && Position >= 0)
				{
					SellMarket();
				}

				_prevRsi = rsiValue;
				_prevMom = momValue;
			})
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, rsi);
			DrawOwnTrades(area);
		}
	}
}