GitHub で見る

アリヘイク トレーダー戦略

MetaTrader 4 エキスパートアドバイザー alliheik.mq4 の変換。この戦略は、二重平滑化された平均足ローソク体と、前方にシフトされた Alligator の「ジョー」移動平均を組み合わせたものです。エントリーは、平滑化プロセス後に平均足バッファーが交差するときに発生します。イグジットは、ジョークロスオーバーフィルター、オプションの固定ターゲット、および価格ベースのトレーリングストップに依存します。

取引ロジック

  • 平均足建設
    • PreSmoothMethod / PreSmoothPeriod を使用して、生の始値、高値、安値、終値をスムーズに表示します。
    • 平滑化された価格から古典的な平均足キャンドルを作成します。
    • ローソクの色に応じて高値/安値バッファーを交換します (強気の場合は安値/高値の順序が維持され、弱気の場合はそれらが逆転します)。
    • 2 番目のスムージング パス (PostSmoothMethod / PostSmoothPeriod) を条件付きバッファーに適用します。これらは信号ルールで比較される値です。
  • 信号の定義
    • Long: 現在の下位バッファは上位バッファより下にありますが、前のバーは反対または等しい関係にあります。
    • 短い: 現在の下位バッファーは上位バッファーの上にありますが、前のバーは反対または等しい関係にあります。
  • ジョーフィルターとトレーリング
    • Alligator ジョーは、JawsPeriod バーの移動平均で、JawsShift バーを前方に移動し、JawsPrice を供給します。
    • ポジションを自動的に決済するには、Close[6] (6 バー前) がジョーを通過する必要があります。
    • Close[6] とジョーの差が 8 ポイントに達し、ジョーを通じて逆転すると、ポジションはクローズされます。
    • TrailingStopPoints がゼロより大きい場合、ローソク足が有利な側に達すると、ストップ価格は Close[6] に従います。
  • ストップとターゲット
    • StopLossPointsTakeProfitPoints は、入場時に適用されるオプションの固定距離です。
    • トレーリングロジックは、トレードに有利に動くと保護ストップを上書きします。

デフォルトパラメータ

パラメータ デフォルト 説明
CandleType TimeSpan.FromHours(1).TimeFrame() すべての計算に使用される時間枠。
JawsPeriod 144 Alligator ジョー移動平均の長さ。
JawsShift 8 ジョーの前方変位 (バーの数)。
JawsMethod シンプル ジョーの移動平均タイプ (単純、指数、平滑化、加重)。
JawsPrice 閉じる ジョーに供給される価格コンポーネント (終値/始値/高値/安値/中央値/標準/加重値)。
PreSmoothMethod 指数関数的 平均足を計算する前に、生の OHLC 値を平滑化するために使用される移動平均。
PreSmoothPeriod 21 平滑化前の平均の期間。
PostSmoothMethod 加重 条件付き平均足バッファに適用される移動平均。
PostSmoothPeriod 1 平滑化後の平均の期間 (1 は元のバッファーを保持します)。
StopLossPoints 0 停止距離をポイント単位で固定 (0 無効)。
TrailingStopPoints 0 Close[6] に基づくトレーリング ストップの距離 (0 無効)。
TakeProfitPoints 225 テイクプロフィット距離 (ポイント単位) (0 無効)。
OrderVolume 0.1 エントリーのロットサイズ。

使用されるインジケーター

  • 事前平滑化 MA (始値、高値、安値、終値の 4 つの並列シリーズ)。
  • 平準化された価格が牽引する平均足の再構築。
  • エントリーシグナルを形成する条件付きバッファーの平滑化後の MA。
  • Alligator 調整可能なタイプ、シフト、および適用価格を備えたジョー移動平均。

エントリーとエグジットの概要

  • 平滑化された下位バッファーが上位バッファーを下回っており、前のバーが強気ではなかった場合 (上記のクロス条件)、「ロング」と入力します
  • Exit Long の場合:
    • Close[6] は、以前顎の上にいた後、顎の下に戻り、距離が 8 ポイント以上に達しました。または
    • TakeProfitPoints 目標を達成しました。または
    • StopLossPoints/TrailingStopPoints の停留所に到達しました。
  • **平滑化された下位バッファーが上位バッファーの上を横切り、前のバーが弱気ではなかった場合は、ショートを入力します。
  • イグジットショートは次の場合に行われます。
    • Close[6] は以前顎の下にいた後、顎の上に戻り、距離が 8 ポイント以上に達しました。または
    • TakeProfitPoints 目標を達成しました。または
    • StopLossPoints/TrailingStopPoints の停留所に到達しました。

変換メモ

  • この戦略は、元の EA の isOrderAllowed() チェックを反映して、バーごとに 1 つの取引を強制します。
  • StockSharp 戦略はブローカー側の MT4 注文に依存できないため、保護的なストップとターゲットは内部でシミュレートされます。
  • ジョー移動平均には履歴値が保存されるため、前方シフトにより iMA の動作が ma_shift = JawsShift で再現されます。
  • すべての計算では、StockSharp の高レベルの API 要件と一致する 10 進算術とインジケーター バインディングが使用されます。

リスクと使用法

  • 同じ商品でロングとショートの両方の取引向けに設計されています。
  • ジョーシフトと平均足のスムージングが中期的な変動を強調できるトレンド市場で最も効果的です。
  • 金融商品のボラティリティに合わせて TrailingStopPointsTakeProfitPoints を調整することを検討してください。
  • ライブデプロイの前に必ず紙のアカウントでバックテストとフォワードテストを行ってください。
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Alliheik Trader: uses smoothed Heiken Ashi candles (EMA of OHLC)
/// with Alligator jaw (long SMA) as trend filter.
/// Entry on HA color change above/below jaw, exit on reversal.
/// </summary>
public class AlliheikTraderStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _smoothPeriod;
	private readonly StrategyParam<int> _jawPeriod;

	private decimal _prevHaOpen;
	private decimal _prevHaClose;
	private bool _prevBullish;
	private bool _hasPrev;
	private decimal _entryPrice;

	public AlliheikTraderStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");

		_smoothPeriod = Param(nameof(SmoothPeriod), 6)
			.SetDisplay("Smooth Period", "EMA period for HA smoothing.", "Indicators");

		_jawPeriod = Param(nameof(JawPeriod), 144)
			.SetDisplay("Jaw Period", "SMA period for Alligator jaw.", "Indicators");
	}

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public int SmoothPeriod
	{
		get => _smoothPeriod.Value;
		set => _smoothPeriod.Value = value;
	}

	public int JawPeriod
	{
		get => _jawPeriod.Value;
		set => _jawPeriod.Value = value;
	}

	/// <inheritdoc />
	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();

		_prevHaOpen = 0;
		_prevHaClose = 0;
		_prevBullish = false;
		_hasPrev = false;
		_entryPrice = 0;
	}

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

		_prevHaOpen = 0;
		_prevHaClose = 0;
		_prevBullish = false;
		_hasPrev = false;
		_entryPrice = 0;

		var ema = new ExponentialMovingAverage { Length = SmoothPeriod };
		var jaw = new SimpleMovingAverage { Length = JawPeriod };

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

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

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

		var close = candle.ClosePrice;

		// Compute smoothed Heiken Ashi
		var haClose = (candle.OpenPrice + candle.HighPrice + candle.LowPrice + close) / 4m;
		var haOpen = _prevHaOpen == 0
			? (candle.OpenPrice + close) / 2m
			: (_prevHaOpen + _prevHaClose) / 2m;

		var bullish = haClose > haOpen;

		if (!_hasPrev)
		{
			_prevHaOpen = haOpen;
			_prevHaClose = haClose;
			_prevBullish = bullish;
			_hasPrev = true;
			return;
		}

		var colorChange = bullish != _prevBullish;

		// Exit on color change
		if (Position > 0 && colorChange && !bullish)
		{
			SellMarket();
			_entryPrice = 0;
		}
		else if (Position < 0 && colorChange && bullish)
		{
			BuyMarket();
			_entryPrice = 0;
		}

		// Entry on color change confirmed by jaw filter
		if (Position == 0 && colorChange)
		{
			if (bullish && close > jawVal)
			{
				_entryPrice = close;
				BuyMarket();
			}
			else if (!bullish && close < jawVal)
			{
				_entryPrice = close;
				SellMarket();
			}
		}

		_prevHaOpen = haOpen;
		_prevHaClose = haClose;
		_prevBullish = bullish;
	}
}