GitHub で見る

10 Pips 戦略

このヘッジ戦略は同時にロングとショートのポジションを開きます。各ポジションは価格単位で計測された固定のテイクプロフィットとストップロスレベルを使用し、トレーリングストップで保護することができます。一方のサイドがクローズすると、戦略は即座に同じ方向で新しいポジションを開き、両サイドをアクティブに保ちます。

パラメーター

  • TakeProfitBuy – ロングポジションのテイクプロフィット距離。
  • StopLossBuy – ロングポジションのストップロス距離。
  • TrailingStopBuy – ロングポジションのトレーリングストップ距離。
  • TakeProfitSell – ショートポジションのテイクプロフィット距離。
  • StopLossSell – ショートポジションのストップロス距離。
  • TrailingStopSell – ショートポジションのトレーリングストップ距離。
  • Volume – すべてのトレードに使用する注文サイズ。

注意事項

  • ポジションは成行注文で開かれます。
  • 保護注文は各サイドに対して個別に登録されます。
  • トレーリングストップは市場が有利な方向に動いたときに更新されます。
using System;
using System.Linq;
using System.Collections.Generic;

using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Simple breakout strategy that enters on momentum moves
/// with fixed take profit and stop loss protection.
/// </summary>
public class TenPipsStrategy : Strategy
{
	private readonly StrategyParam<decimal> _takeProfit;
	private readonly StrategyParam<decimal> _stopLoss;
	private readonly StrategyParam<int> _lookback;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _entryPrice;
	private decimal _previousRoc;
	private bool _hasPreviousRoc;

	/// <summary>Take profit distance.</summary>
	public decimal TakeProfit { get => _takeProfit.Value; set => _takeProfit.Value = value; }
	/// <summary>Stop loss distance.</summary>
	public decimal StopLoss { get => _stopLoss.Value; set => _stopLoss.Value = value; }
	/// <summary>Lookback period for momentum.</summary>
	public int Lookback { get => _lookback.Value; set => _lookback.Value = value; }
	/// <summary>Candle type.</summary>
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	/// <summary>
	/// Initializes a new instance of the strategy.
	/// </summary>
	public TenPipsStrategy()
	{
		_takeProfit = Param(nameof(TakeProfit), 500m)
			.SetDisplay("Take Profit", "Take profit distance", "Risk")
			.SetGreaterThanZero();
		_stopLoss = Param(nameof(StopLoss), 300m)
			.SetDisplay("Stop Loss", "Stop loss distance", "Risk")
			.SetGreaterThanZero();
		_lookback = Param(nameof(Lookback), 30)
			.SetDisplay("Lookback", "Momentum lookback period", "Indicators")
			.SetGreaterThanZero();
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles", "General");
	}

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

	/// <inheritdoc />
	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_entryPrice = 0m;
		_previousRoc = 0m;
		_hasPreviousRoc = false;
	}

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

		_entryPrice = 0;
		_previousRoc = 0m;
		_hasPreviousRoc = false;

		var roc = new RateOfChange { Length = Lookback };

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

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

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

		if (!IsFormedAndOnlineAndAllowTrading())
			return;

		var close = candle.ClosePrice;
		var buySignal = _hasPreviousRoc && _previousRoc <= 4m && rocValue > 4m;
		var sellSignal = _hasPreviousRoc && _previousRoc >= -4m && rocValue < -4m;

		if (Position == 0)
		{
			if (buySignal)
			{
				BuyMarket();
				_entryPrice = close;
			}
			else if (sellSignal)
			{
				SellMarket();
				_entryPrice = close;
			}
		}
		else if (Position > 0)
		{
			if (close >= _entryPrice + TakeProfit || close <= _entryPrice - StopLoss)
			{
				SellMarket(Math.Abs(Position));
			}
		}
		else if (Position < 0)
		{
			if (close <= _entryPrice - TakeProfit || close >= _entryPrice + StopLoss)
			{
				BuyMarket(Math.Abs(Position));
			}
		}

		_previousRoc = rocValue;
		_hasPreviousRoc = true;
	}
}