GitHub で見る

Exp XRSI ヒストグラム Vol 戦略

概要

この戦略は元のMQL5エキスパートアドバイザー Exp_XRSI_Histogram_Vol のC#変換です。インジケーターが生成する5つの色状態を解釈することで、ボリューム加重RSIヒストグラムのブレイクアウトを取引します。スクリプトはキャンドルサブスクリプションを通じて提供される任意の時間軸で動作し、StockSharpの高レベル戦略APIに基づいて構築されています。

戦略ロジック

  1. 選択した時間軸でRSIを計算し、オシレーターを中心にするために50を引く。
  2. 中心化されたRSI値を選択したボリュームストリーム(ティックまたは実ボリューム)で乗算して、強い活動のキャンドルを強調する。
  3. 同じ移動平均メソッドと長さを使用して加重RSIと生ボリュームの両方を平滑化する。
  4. 平滑化されたボリュームに4つのユーザー定義乗数を掛けることで適応しきい値を構築する。結果のヒストグラムは次の色状態に分類される:
    • 0 – 強い強気インパルス(HighLevel2より上)。
    • 1 – 中程度の強気インパルス(HighLevel1HighLevel2の間)。
    • 2 – ニュートラルゾーン。
    • 3 – 中程度の弱気インパルス(LowLevel2LowLevel1の間)。
    • 4 – 強い弱気インパルス(LowLevel2より下)。
  5. エントリーとエグジットのルールはMQLロジックを反映する:
    • 状態1より上にあった後にヒストグラムが状態1に変わったときに最初のロングに入る(色が弱気/ニュートラルから中程度の強気に減少)。
    • 状態0より上にあった後にヒストグラムが状態0に変わったときに2番目のロングに入る。
    • 状態3より下にあった後にヒストグラムが状態3に変わったときに最初のショートに入る。
    • 状態4より下にあった後にヒストグラムが状態4に変わったときに2番目のショートに入る。
    • ヒストグラムが状態0または1のときにショートポジションをクローズする。
    • ヒストグラムが状態3または4のときにロングポジションをクローズする。
  6. シグナル生成は元のインジケーターバッファーインデクシングを模倣するためにSignalBarバー分後ろにシフトできます。

各方向に対してMm1Mm2乗数を通じて2つのスケーリングエントリーがサポートされています。ヘルパーメソッドは新しいポジションを開く前に反対のポジションをフラット化し、レガシー取引管理コードの動作を複製します。

資金管理と保護

  • Mm1Mm2は戦略のVolumeプロパティに適用されるボリューム乗数です(Volumeが未設定の場合はデフォルト値1が使用される)。
  • グローバルストップロスとテイクプロフィットは、価格ステップと対応するポイント値の両方が正の場合にStartProtectionを通じてアクティブ化されます。価格ステップの数として解釈されます。

パラメーター

パラメーター 説明
CandleType キャンドルとインジケーター計算に使用される時間軸。
RsiPeriod RSIの長さ。
VolumeMode ティックボリュームと実ボリュームの選択。ボリュームデータが欠落しているときティックモードは1単位にフォールバック。
HighLevel2, HighLevel1, LowLevel1, LowLevel2 ヒストグラムしきい値を構築するために平滑化されたボリュームをスケールする乗数。
MaMethod, MaLength, MaPhase 平滑化設定。非対応メソッド(Parabolic、T3、Vidya、Ama)は単純移動平均にフォールバック。MaPhaseは完全性のために保持されますが、Jurikのような高度なメソッドにのみ影響します。
SignalBar ヒストグラムの色を読む際に評価する閉じたバーの数。
Mm1, Mm2 各方向の最初と2番目のポジションのボリューム乗数。
BuyPosOpen, SellPosOpen, BuyPosClose, SellPosClose ロング/ショートの開閉ロジックを有効または無効にする。
StopLossPoints, TakeProfitPoints 価格ステップで表された保護オフセット。

デフォルト値

  • キャンドルタイプ:4時間時間軸。
  • RSI長さ:14。
  • ボリュームモード:ティックボリューム。
  • ヒストグラムしきい値:HighLevel2 = 17HighLevel1 = 5LowLevel1 = -5LowLevel2 = -17
  • 移動平均:長さ12、フェーズ15のSMA。
  • シグナルバーオフセット:1バー。
  • 資金管理:Mm1 = 0.1Mm2 = 0.2
  • ストップ:ストップロス1000ポイント、テイクプロフィット2000ポイント(有効な価格ステップが利用可能な場合にのみ適用)。

注意事項

  • 戦略は完成したキャンドルに依存し、未完成の更新を無視します。
  • JurikスムージングはStockSharpのJurikMovingAverageを通じてサポートされています。ネイティブ同等物が欠けているため、他のレガシーメソッド(ParMA、T3、VIDYA、AMA)はSMAに戻ります。
  • インジケーターはキャンドルのTotalVolumeを使用します。ボリュームがゼロのとき、ティックモードはシグナルを抑制しないようにフォールバックウェイト1を使用します。
  • 視覚的分析のため、RSI自体がキャンドルや取引マーカーとともにプロットされます。より深い診断が必要な場合は追加のチャート要素を添付できます。
using System;
using System.Collections.Generic;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Exp XRSI Histogram Vol strategy. Uses RSI level crossovers.
/// </summary>
public class ExpXrsiHistogramVolStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _rsiPeriod;

	private decimal? _prevRsi;

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

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

	public ExpXrsiHistogramVolStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe", "General");

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

	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_prevRsi = null;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevRsi = null;
		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 rsiVal)
	{
		if (candle.State != CandleStates.Finished) return;
		if (!IsFormedAndOnlineAndAllowTrading()) { _prevRsi = rsiVal; return; }
		if (_prevRsi == null) { _prevRsi = rsiVal; return; }
		if (_prevRsi.Value < 45m && rsiVal >= 55m && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
		else if (_prevRsi.Value > 55m && rsiVal <= 45m && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
		_prevRsi = rsiVal;
	}
}