GitHub で見る

ゴナスカルプ戦略

概要

Gonna Scalp 戦略は、高頻度の MetaTrader エキスパート アドバイザーを StockSharp の高レベル API に移植したものです。このシステムは、支配的な市場トレンドを尊重しながら、短期チャートでの急速な平均回帰エントリーを探します。確認は、取引を許可する前に、モメンタム、CCI、ATR、確率オシレーター、および MACD フィルターを評価する投票メカニズムによって生成されます。一度にオープンできるポジションは 1 つだけであり、すべての取引は MetaTrader ポイントで表される固定のストップロスとテイクプロフィットの距離によって保護されます。

取引ロジック

  1. インジケーターの準備
    • 典型的な価格に基づいて計算された高速および低速加重移動平均 (WMA)。
    • モメンタム (期間 14) は取引時間枠で評価され、中立値 100 からの絶対距離に変換されます。
    • コモディティ チャネル インデックス (期間 20) と平均トゥルー レンジ (期間 12) が方向性フィルターとして使用されます。
    • Stochastic オシレーター %K/%D (5/3/3) と MACD (12/26/9) が同じローソク足シリーズで処理されました。
  2. シグナル投票
    • 現在の読み取り値が元の MetaTrader コードで特定されたトレンドをサポートしている場合、各インジケーターは強気側または弱気側に 1 票を投じます。
    • この戦略は、最近の 3 つのモメンタム距離を収集し、新しい取引を許可する前に、そのうちの少なくとも 1 つが設定可能なしきい値を超える必要があります。
    • 追加の構造チェックでは、ロングの場合は 2 キャンドル前のバーの安値が前のバーの高値を下回っていることが要求されます (ショートの場合はミラー条件)。
  3. 注文の実行
    • 強気の投票が弱気の投票を上回り、すべてのフィルターが一致すると、戦略は設定されたロット サイズを使用してロング ポジションをオープンします。
    • 弱気票が強気票を上回り、モメンタムフィルターが承認すると、ショートポジションがオープンします。
  4. リスク管理
    • 各オープン取引には、MetaTrader ポイントで測定され、商品の価格ステップに変換される固定のストップロスとテイクプロフィットの距離が伴います。
    • いずれかのレベルが突破されると、保護ロジックにより現在のローソク足のポジションが閉じられます。

主要なパラメータ

名前 説明 デフォルト
TradeVolume 数量調整後のロット単位の基本注文サイズ。 0.01
FastMaPeriod 高速 WMA フィルターの長さ。 1
SlowMaPeriod 低速 WMA フィルターの長さ。 5
MomentumPeriod モメンタムインジケーターによって使用されるバーの数。 14
MomentumBuyThreshold ロングエントリーに必要な最小絶対モメンタム偏差。 0.3
MomentumSellThreshold ショートエントリーに必要な最小絶対モメンタム偏差。 0.3
StopLossSteps ストップロス距離は MetaTrader ポイントで表されます。 200
TakeProfitSteps MetaTrader ポイントで表されるテイクプロフィット距離。 200
CandleType すべてのインジケーターに使用される時間枠 (デフォルトは 5 分足ローソク足)。 M5

使用上の注意

  • TradeVolumeを調整して、ストラテジーのボリュームを取引商品に合わせます。実装により、交換ロット ステップに自動的に正規化されます。
  • ストップロスとテイクプロフィットのパラメータは、MetaTrader ポイントで動作します。これらは、機器の精度に基づいて機器の価格単位に変換されます。
  • モメンタム履歴バッファーがあるため、投票ロジックがシグナルを生成するには、少なくとも 3 つの完了したローソク足が必要です。
  • この戦略は意図的にピラミッド化を避けています。新しい取引は、リスク管理または逆のシグナルによって前のポジションがクローズされるまで開始されません。
  • 戦略を StockSharp チャートに接続して、シグナル検証のために WMA シリーズ、確率シリーズ、および MACD シリーズを視覚化できます。
namespace StockSharp.Samples.Strategies;

using System;

using Ecng.Common;

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

/// <summary>
/// Gonna Scalp strategy: WMA crossover with CCI momentum filter.
/// Buys when fast WMA above slow WMA and CCI above -100.
/// Sells when fast WMA below slow WMA and CCI below 100.
/// </summary>
public class GonnaScalpStrategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastPeriod;
	private readonly StrategyParam<int> _slowPeriod;
	private readonly StrategyParam<int> _cciPeriod;

	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 int CciPeriod
	{
		get => _cciPeriod.Value;
		set => _cciPeriod.Value = value;
	}

	public GonnaScalpStrategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");

		_fastPeriod = Param(nameof(FastPeriod), 10)
			.SetGreaterThanZero()
			.SetDisplay("Fast WMA", "Fast WMA period", "Indicators");

		_slowPeriod = Param(nameof(SlowPeriod), 30)
			.SetGreaterThanZero()
			.SetDisplay("Slow WMA", "Slow WMA period", "Indicators");

		_cciPeriod = Param(nameof(CciPeriod), 14)
			.SetGreaterThanZero()
			.SetDisplay("CCI Period", "CCI period", "Indicators");
	}

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

		var fast = new WeightedMovingAverage { Length = FastPeriod };
		var slow = new WeightedMovingAverage { Length = SlowPeriod };
		var cci = new CommodityChannelIndex { Length = CciPeriod };

		decimal? prevFast = null;
		decimal? prevSlow = null;

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(fast, slow, cci, (candle, fastVal, slowVal, cciVal) =>
			{
				if (candle.State != CandleStates.Finished)
					return;

				if (!IsFormedAndOnlineAndAllowTrading())
					return;

				if (prevFast.HasValue && prevSlow.HasValue)
				{
					var crossUp = prevFast.Value <= prevSlow.Value && fastVal > slowVal;
					var crossDown = prevFast.Value >= prevSlow.Value && fastVal < slowVal;

					if (crossUp && cciVal > -100m && Position <= 0)
						BuyMarket();
					else if (crossDown && cciVal < 100m && Position >= 0)
						SellMarket();
				}

				prevFast = fastVal;
				prevSlow = slowVal;
			})
			.Start();

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