GitHub で見る

AMkA Signal 戦略

概要

この戦略はカウフマン適応型移動平均(KAMA)の導関数と標準偏差に基づくボラティリティフィルターを組み合わせて使用します。KAMAの変化率が動的な閾値を超えるとロングポジションを開き、負の閾値を下回るとショートポジションを開きます。閾値はKAMAの変化の標準偏差にユーザー定義のファクターを掛けて計算されます。

パラメーター

  • KAMA Length – KAMAインジケーターのルックバック期間。
  • Fast Period – KAMAスムージングで使用する高速EMAの期間。
  • Slow Period – KAMAスムージングで使用する低速EMAの期間。
  • Deviation Multiplier – シグナル閾値を形成するために標準偏差に適用する乗数。
  • Take Profit – 自動利益確定のパーセンテージ。
  • Stop Loss – 保護ストップのパーセンテージ。
  • Candle Type – 計算に使用するローソク足の時間軸。

トレードロジック

  1. 選択した時間軸のローソク足を購読する。
  2. 各ローソク足のKAMAを計算し、前の値からの変化を算出する。
  3. 変化値で標準偏差インジケーターを更新する。
  4. 変化がDeviation Multiplier * StdDevを超えたとき、ポジションを開くまたは閉じる:
    • 変化が閾値より大きい場合:ショートポジションをクローズしてロングを開く。
    • 変化が負の閾値より小さい場合:ロングポジションをクローズしてショートを開く。
  5. テイクプロフィットとストップロスの保護注文はStartProtectionを使用して自動管理される。

注記

この戦略は完成したローソク足のみで動作し、ソースコードのインデントにはタブを使用します。すべてのコメントは規定に従い英語で記述されています。

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>
/// AMkA based strategy using KAMA derivative and standard deviation filter.
/// Buys when KAMA rises above volatility threshold and sells when it falls below.
/// </summary>
public class AmkaSignalStrategy : Strategy
{
	private readonly StrategyParam<int> _length;
	private readonly StrategyParam<decimal> _deviationMultiplier;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _prevKama;
	private bool _hasPrev;

	public int Length { get => _length.Value; set => _length.Value = value; }
	public decimal DeviationMultiplier { get => _deviationMultiplier.Value; set => _deviationMultiplier.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public AmkaSignalStrategy()
	{
		_length = Param(nameof(Length), 10)
			.SetGreaterThanZero()
			.SetDisplay("KAMA Length", "Lookback period for the adaptive moving average", "Indicator");

		_deviationMultiplier = Param(nameof(DeviationMultiplier), 1.0m)
			.SetGreaterThanZero()
			.SetDisplay("Deviation Multiplier", "Multiplier for standard deviation filter", "Indicator");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe for indicator calculation", "General");
	}

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

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

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

		var kama = new KaufmanAdaptiveMovingAverage { Length = Length };
		var stdev = new StandardDeviation { Length = Length };

		SubscribeCandles(CandleType).Bind(kama, stdev, ProcessCandle).Start();
	}

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

		if (!_hasPrev)
		{
			_prevKama = kamaValue;
			_hasPrev = true;
			return;
		}

		var delta = kamaValue - _prevKama;
		_prevKama = kamaValue;

		if (stdevValue <= 0) return;

		var threshold = stdevValue * DeviationMultiplier;

		if (delta > threshold && Position <= 0)
		{
			if (Position < 0) BuyMarket();
			BuyMarket();
		}
		else if (delta < -threshold && Position >= 0)
		{
			if (Position > 0) SellMarket();
			SellMarket();
		}
	}
}