GitHub で見る

BuySell戦略

この戦略はMetaTraderのBuySellエキスパートをエミュレートします。移動平均線とAverage True Range(ATR)を組み合わせてトレンドの反転を検出します。 移動平均線が上向きになると市場はブル(強気)と判断し、下向きになるとベア(弱気)と判断します。 前のバーが逆の状態であった場合のみ取引を開始し、反転を確認します。オプションのストップロスとテイクプロフィットのレベルは価格ポイントで表されます。

詳細

  • エントリー条件
    • ロング: 移動平均線が下降から上昇に転じ、前のバーが弱気であった場合。
    • ショート: 移動平均線が上昇から下降に転じ、前のバーが強気であった場合。
  • エグジット条件
    • ロング: 移動平均線が下向きに転じるか、ストップロス/テイクプロフィットが発動した場合。
    • ショート: 移動平均線が上向きに転じるか、ストップロス/テイクプロフィットが発動した場合。
  • インジケーター: 単純移動平均(SMA)とATR。
  • ストップ: ポイント単位のストップロスとテイクプロフィットの両方。
  • 権限: ロングとショートのポジションの開閉をそれぞれ許可または禁止する個別のフラグ。
  • デフォルトの時間軸: 4時間足。

パラメーター

名前 デフォルト 説明
MaPeriod 14 移動平均線の期間。
AtrPeriod 60 ATRの期間。
StopLoss 1000 価格ポイント単位のストップロス。
TakeProfit 2000 価格ポイント単位のテイクプロフィット。
AllowLongEntry true ロングポジションの開設を許可。
AllowShortEntry true ショートポジションの開設を許可。
AllowLongExit true ロングポジションのクローズを許可。
AllowShortExit true ショートポジションのクローズを許可。
CandleType H4 計算に使用する時間軸。

使用方法

  1. 戦略をStockSharpソリューションに追加します。
  2. 必要に応じてパラメーターを設定します。
  3. ライブまたはバックテストモードで戦略を実行します。取引はBuyMarketおよびSellMarket注文を使用して実行されます。

このアプローチは、ATRが捉えるボラティリティ変化を伴うトレンド反転が見られる市場に適しています。

using System;
using System.Collections.Generic;

using Ecng.Common;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Buy/Sell strategy based on EMA crossover.
/// </summary>
public class BuySellStrategy : Strategy
{
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevFast;
	private decimal _prevSlow;
	private bool _hasPrev;

	public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
	public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public BuySellStrategy()
	{
		_fastPeriod = Param(nameof(FastPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("Fast Period", "Fast EMA period", "Indicator");
		_slowPeriod = Param(nameof(SlowPeriod), 28)
			.SetGreaterThanZero()
			.SetDisplay("Slow Period", "Slow EMA period", "Indicator");
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle type", "General");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFast = 0;
		_prevSlow = 0;
		_hasPrev = false;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };

		SubscribeCandles(CandleType)
			.Bind(fast, slow, ProcessCandle)
			.Start();
	}

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

		if (!_hasPrev)
		{
			_prevFast = fastVal;
			_prevSlow = slowVal;
			_hasPrev = true;
			return;
		}

		var crossUp = _prevFast <= _prevSlow && fastVal > slowVal;
		var crossDown = _prevFast >= _prevSlow && fastVal < slowVal;

		if (crossUp && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		else if (crossDown && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}

		_prevFast = fastVal;
		_prevSlow = slowVal;
	}
}