GitHub で見る

毎日の目標戦略

概要

DailyTargetStrategy は、MetaTrader 4 エキスパート アドバイザー「デイリー ターゲット」を複製します。この戦略は、オープンポジションの取引を継続します。 現在の暦日の利益と損失の合計が、設定された利益目標に達するか、最大損失制限に違反します。として いずれかのしきい値に達するとすぐに、アクティブな注文はすべてキャンセルされ、ポジションがフラット化されるため、取引は 次の日が始まります。

取引ロジック

  1. スタートアップ
    • この戦略は、OnStarted 中に ResetDailySnapshot を呼び出して、現在の日付と実現された損益ベースラインを保存します。
    • SubscribeLevel1() は、変動利益を正確に評価するために必要な買値/売値の更新を提供します。
    • SubscribeTrades() は最後に約定した価格を取得し、相場が見つからない場合のフォールバックを提供します。
    • 1 分間の Timer ティックにより、市場データが到着しない場合でも日付の変更が確実に検出されます。
  2. 損益評価
    • EvaluateDailyThresholds は実現損益 (現在の PnL から保存されたベースラインを差し引いたもの) を再計算し、変動損益を追加します。 最新の買値/買値または最後の取引価格から計算されます。
    • 1 日の合計損益が設定された目標を超えるか、マイナスの損失制限を下回る場合、戦略は呼び出しを行います。 TriggerDailyStop
  3. 非常口
    • TriggerDailyStop は情報ログ エントリを書き込み、すべての未決注文をキャンセルし、適切な成行注文を送信します。 残りの長時間または短時間の露出を平坦化します。
    • _dailyStopTriggeredは同日中の再入場を禁止します。カレンダーの日付が変わると、ResetDailySnapshot はこれをクリアします フラグを立てて、新しい損益ベースラインを記録します。

パラメーター

名前 デフォルト 説明
DailyTarget 10 ポートフォリオ通貨での利益目標。 1 日の合計損益がこの値以上になると、その日の残りの取引は停止します。
DailyMaxLoss 0 ポートフォリオ通貨の最大許容損失。損失フィルターを無効にするには、ゼロに設定します。 1 日の合計損益がマイナスのしきい値を下回ると、その日の取引は停止されます。

注意事項

  • ストラテジーは、ストラテジー インスタンスに割り当てられたプライマリ Security のみを管理し、その単一シンボルの動作を反映します。 MQLの専門家。
  • 変動損益では、ロング ポジションには最適な買値が使用され、ショート ポジションには最適な売値が使用されます。相場が利用できない場合は、最後の取引 価格は評価の停止を避けるためのフォールバックとして機能します。
  • Python ポートは提供されません。このパッケージには、C# の高レベル実装のみが含まれています。
namespace StockSharp.Samples.Strategies;

using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;

/// <summary>
/// Daily Target strategy: TEMA crossover.
/// Buys when fast TEMA crosses above slow TEMA, sells on cross below.
/// </summary>
public class DailyTargetStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;

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

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

	public DailyTargetStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast TEMA", "Fast TEMA period", "Indicators");
		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow TEMA", "Slow TEMA period", "Indicators");
	}

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

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevFast = 0;
		_prevSlow = 0;
		_hasPrev = false;
		var fast = new ExponentialMovingAverage { Length = FastPeriod };
		var slow = new ExponentialMovingAverage { Length = SlowPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fast, slow, ProcessCandle).Start();
	}

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

		if (_hasPrev)
		{
			if (_prevFast <= _prevSlow && fastValue > slowValue && Position <= 0)
				BuyMarket();
			else if (_prevFast >= _prevSlow && fastValue < slowValue && Position >= 0)
				SellMarket();
		}
		else
		{
			if (fastValue > slowValue && Position <= 0)
				BuyMarket();
			else if (fastValue < slowValue && Position >= 0)
				SellMarket();
		}

		_prevFast = fastValue;
		_prevSlow = slowValue;
		_hasPrev = true;
	}
}