GitHub で見る

Hpcs Inter7 戦略

概要

Hpcs Inter7 戦略は、MetaTrader 4 エキスパート アドバイザー _HPCS_Inter7_MT4_EA_V01_We.mq4 から変換された Bollinger バンド ブレイクアウト システムです。このアルゴリズムは、選択したローソク足シリーズで計算された標準の Bollinger バンドを監視します。価格がバンドの外側を横切ると、これを勢いのブレイクアウトと解釈し、ブレイクアウトの方向にポジションを開きます。新しいエントリーごとに、ストラテジーはストップロスとテイクプロフィットの両方のターゲットをエントリー価格から一定の距離に即座に配置し、元のエキスパートアドバイザーの動作を再現します。

取引ロジック

  • ショートエントリー: 前のローソク足が下位バンドを上回って終了し、最新のクローズしたローソク足が下位バンドを下回って終了した場合、この戦略は市場で売りを開始します。これにより、元の状態 Close[0] < LowerBand[0] && Close[1] > LowerBand[1] が再現されます。
  • ロングエントリー: 前のローソク足が上部バンドを下回って終了し、最新のクローズしたローソク足が上部バンドを上回って終了すると、この戦略は市場での買いを開始します。これにより、MQL 実装から Close[0] > UpperBand[0] && Close[1] < UpperBand[1] が複製されます。
  • ローソクごとの単一取引: アルゴリズムは、最後の注文を生成したローソクの開始時間を記憶します。同じローソク足の新しいシグナルは重複取引を避けるために無視され、MQL4 の gdt_Candle ガード変数がミラーリングされます。
  • 保護注文: 新しいポジションがオープンされた直後、ストラテジーは設定された距離を使用して SetStopLossSetTakeProfit を呼び出します。どちらもエントリー価格を中心に対称的に配置されるため、ポジションには常に事前定義されたリスクと報酬の目標があります。

パラメーター

名前 説明 デフォルト 最適化可能
BollingerLength Bollinger バンドの構築に使用されるキャンドルの数。 20 はい
BollingerDeviation Bollinger バンド幅の標準偏差乗数。 2 はい
CandleType 計算に使用されるローソク足シリーズ (デフォルトは 1 分の時間枠)。 1分キャンドル いいえ
ProtectionDistancePoints 価格ステップで表されるストップロスとテイクプロフィットの距離。 10 はい

追加メモ

  • この戦略では、StockSharp の高レベルの API (SubscribeCandles().Bind(...)) が使用され、カスタム履歴配列は保存されません。
  • StartProtection() は起動時に有効化されるため、プラットフォームは SetStopLossSetTakeProfit によって発行された保護命令を自動的に管理します。
  • ポジション サイズは、1 ロットの固定量を取引する元のエキスパート アドバイザーと同様に、基本の Strategy.Volume プロパティによって制御されます。
  • この戦略は、元の EA が導入された FX 金融商品向けに設計されましたが、意味のある Bollinger バンド シグナルと有効な PriceStep 値を提供するあらゆる証券に使用できます。
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Strategy converted from _HPCS_Inter7_MT4_EA_V01_We.mq4.
/// Sells when price crosses below the lower Bollinger band and buys when price crosses above the upper band.
/// </summary>
public class HpcsInter7Strategy : Strategy
{
	private readonly StrategyParam<int> _bollingerLength;
	private readonly StrategyParam<decimal> _bollingerDeviation;
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<decimal> _bandPercent;

	private decimal? _prevClose;
	private decimal? _prevLower;
	private decimal? _prevUpper;

	/// <summary>
	/// Initializes a new instance of the <see cref="HpcsInter7Strategy"/> class.
	/// </summary>
	public HpcsInter7Strategy()
	{
		_bollingerLength = Param(nameof(BollingerLength), 20)
			.SetGreaterThanZero()
			.SetDisplay("Bollinger Length", "Number of candles included in the Bollinger Bands calculation", "Indicators");

		_bollingerDeviation = Param(nameof(BollingerDeviation), 2m)
			.SetGreaterThanZero()
			.SetDisplay("Bollinger Deviation", "Standard deviation multiplier for the Bollinger Bands", "Indicators");

		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Time frame used for Bollinger Bands", "General");

		_bandPercent = Param(nameof(BandPercent), 0.01m)
			.SetGreaterThanZero()
			.SetDisplay("Band Percent", "MA percentage band width", "Indicators");
	}

	/// <summary>
	/// Bollinger Bands length.
	/// </summary>
	public int BollingerLength
	{
		get => _bollingerLength.Value;
		set => _bollingerLength.Value = value;
	}

	/// <summary>
	/// Bollinger Bands deviation multiplier.
	/// </summary>
	public decimal BollingerDeviation
	{
		get => _bollingerDeviation.Value;
		set => _bollingerDeviation.Value = value;
	}

	/// <summary>
	/// Candle type used for calculations.
	/// </summary>
	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public decimal BandPercent
	{
		get => _bandPercent.Value;
		set => _bandPercent.Value = value;
	}

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

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevClose = null;
		_prevLower = null;
		_prevUpper = null;

		var bollinger = new ExponentialMovingAverage { Length = BollingerLength };

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(bollinger, ProcessCandle)
			.Start();

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

	private void ProcessCandle(ICandleMessage candle, decimal middle)
	{
		if (candle.State != CandleStates.Finished)
			return;

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		var upper = middle * (1 + BandPercent);
		var lower = middle * (1 - BandPercent);

		if (_prevClose.HasValue && _prevLower.HasValue && _prevUpper.HasValue)
		{
			// Downward cross through the lower band - open short
			if (_prevClose.Value > _prevLower.Value && candle.ClosePrice < lower && Position >= 0)
			{
				SellMarket();
			}
			// Upward cross through the upper band - open long
			else if (_prevClose.Value < _prevUpper.Value && candle.ClosePrice > upper && Position <= 0)
			{
				BuyMarket();
			}
		}

		_prevClose = candle.ClosePrice;
		_prevLower = lower;
		_prevUpper = upper;
	}
}