GitHub で見る

TDSグローバル4

概要

TDSGlobal 4 は、MetaTrader 4 エキスパート アドバイザー「TDSGlobal 4」の変換です。オリジナルのシステムはアレクサンダー・エルダーのトリプルを適用しています 毎日の MACD ヒストグラム (OsMA) の傾きと Williams %R フィルターを組み合わせたスクリーン法。オーダーは次の場合にのみ展開されます。 毎日の勢いはオシレーターの極値と一致し、その後戦略は保留中のSTOで前日のレンジを囲みます。 p注文します。 StockSharp ポートは同じブレイクアウト ロジックを維持し、異なる FX シンボルが段階的に起動されるように正確なスケジューリングを追加します。 赤分、およびオプションのトレーリングストップと構成可能なテイクプロフィットターゲットを使用してオープンエクスポージャーを管理します。

戦略ロジック

より長い時間枠のフィルター

  • MACD の傾き – 最近完了した毎日の MACD の主な値 (高速 EMA 12、低速 EMA 26、シグナル EMA 9) を比較します。バイアスは b です 最新の値が以前の値を上回っている場合は弱気、低い場合は弱気、等しい場合は中立です。
  • Williams %R – 毎日の Williams %R (期間 24) を評価します。長いセットアップは、読み取り値が上限を超えている場合にのみ許可されます。 しきい値 (デフォルトは -25、買われすぎの強さを意味します) ですが、短いセットアップでは値が下限しきい値 (de 故障 -75)。

ブレークアウトの配置

  • 価格レベル – 終了した日次ローソク足ごとに、戦略は前日の高値と安値を記録します。新しい逆指値注文はposです 元の EA の ±1 ポイントのオフセットを模倣して、これらの極端な値 (EntryBufferPips で設定可能) を 1 ピップ超えて調整しました。
  • 距離ガード – 逆指値注文を送信する前に、コードは現在の最良気配とエントリーprとの間に最小ギャップを強制します。 氷 (デフォルトは 16 ピップ、EA の 16 ポイント チェックに一致)。これにより、保留中の注文がマークに近づきすぎてドロップされるのを防ぎます。 ボラティリティが低い場合。
  • 方向性ゲート – 買いストップは、MACD の傾きが正で、Williams %R が強気バイアスを裏付ける場合にのみ作成されます。 S エルストップには負の傾きと弱気圧力を示す Williams %R が必要です。

保留中の注文のメンテナンス

  • 日次リセット – 新しい日次ローソク足が閉じると、残っているすべての未決注文がキャンセルされ、次の取引セッションが開始されます。 白紙の状態で。フィルターで取引が許可されていない場合、その日は注文は行われません。
  • 1 日あたり 1 回の取引 – 特定の日に注文が評価されると (発注されたかスキップされたかにかかわらず)、戦略は待機します。 再評価する前に次の日次終値を確認します。約定されたストップ注文は、同時注文を避けるために反対側の注文を自動的にキャンセルします。 NG/短時間露出。

リスク管理

  • 保護的なストップ – ロングポジションは前日の安値のすぐ下で保護的な出口を継承しますが、ショートポジションは 前回の最高値。これらのレベルは 1 分間のトリガー ストリームで監視されます。
  • テイクプロフィット – 実際の約定価格に対するピップ単位で表されるオプションの固定ターゲット。 TakeProfitPips0 に設定して無効にします ターゲットを有効にして、MT4 設定をミラーリングします。
  • トレーリングストップTrailingStopPips がゼロより大きい場合、戦略はレベル 1 データとトレイルから最良の買値/売値を読み取ります。 価格が取引に有利に動いた場合のストップ。トレーリングレベルを突破すると、ポジションは市場でクローズされます。

スケジュール設定

  • 分ウィンドウ – 異なる通貨ペアでの同時送信を避けるために、EA はシンボル固有の分ウィンドウを使用しました ws。ポートはこの動作を再現します。USDCHF は分 0/8/16/24/32/40/48、GBPUSD 2/10/18/26/34/42/50、USDJPY 4/12/20/28/36/44 を使用します。 /52、ユーロドル 6/14/22/30/38/46/54。他の計器はすべて 1 時間 (0 ~ 59) に戻ります。
  • トリガー ストリーム – 1 分間のキャンドル サブスクリプションにより、毎日の注文のスケジュール設定と日中のストップ/テイクの両方が促進されます。 利益チェック。実際のシグナル評価は、取引日ごとに最初の適格な分間に 1 回だけ発生します。

パラメーター

パラメータ 説明 デフォルト
Volume 逆指値エントリーの注文量。 1
MacdFastPeriod / MacdSlowPeriod / MacdSignalPeriod 毎日の傾きを測定するために使用される MACD 構成。 12 / 26 / 9
WilliamsPeriod Williams %R フィルターをルックバックします。 24
WilliamsBuyLevel ロング注文を有効にする前に、上限しきい値 (通常は -25) が必要です。 -25
WilliamsSellLevel ショートオーダーを有効にする前に、下限しきい値 (通常は -75) が必要です。 -75
TakeProfitPips 利益確定距離 (pips)。 0 はターゲットを無効にします。 999
TrailingStopPips トレーリングストップの距離 (ピップ単位)。 0 は末尾を無効にします。 10
EntryBufferPips 逆指値注文を出す前に、前日の高値/安値を超えてオフセットが追加されました。 1
MinDistancePips 現在の気配から未決注文までの最小ピップ距離。 16
DailyCandleType MACD および Williams %R フィルターをフィードするタイムフレーム。 1 day キャンドル
TriggerCandleType 注文のスケジュールと監視に使用される短い時間枠。 1 minute キャンドル

追加の注意事項

  • C# 実装は、高レベルの StockSharp ヘルパー (SubscribeCandlesBuyStopSellStop、レベル 1 バインディ) に完全に依存しています。 ng) なので、手動で注文配管を行わなくてもプラットフォーム内で再利用できます。
  • アルゴリズムは最良の買値/売値を使用して取引を動かしトリガーするため、トレーリングストップ操作にはレベル 1 データが必要です。 仮想停止。
  • パッケージには Python 翻訳は含まれていません。 C# 戦略と多言語ドキュメントのみが提供されます。
using System;

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

namespace StockSharp.Samples.Strategies;

/// <summary>
/// TDSGlobal 4: EMA crossover with RSI filter and ATR stops.
/// </summary>
public class TdsGlobal4Strategy : Strategy
{
	private readonly StrategyParam<DataType> _candleType;
	private readonly StrategyParam<int> _fastEmaLength;
	private readonly StrategyParam<int> _slowEmaLength;
	private readonly StrategyParam<int> _rsiLength;
	private readonly StrategyParam<int> _atrLength;

	private decimal _prevFast;
	private decimal _prevSlow;
	private decimal _entryPrice;

	public TdsGlobal4Strategy()
	{
		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Timeframe.", "General");
		_fastEmaLength = Param(nameof(FastEmaLength), 12)
			.SetDisplay("Fast EMA", "Fast EMA period.", "Indicators");
		_slowEmaLength = Param(nameof(SlowEmaLength), 26)
			.SetDisplay("Slow EMA", "Slow EMA period.", "Indicators");
		_rsiLength = Param(nameof(RsiLength), 14)
			.SetDisplay("RSI Length", "RSI period.", "Indicators");
		_atrLength = Param(nameof(AtrLength), 14)
			.SetDisplay("ATR Length", "ATR period.", "Indicators");
	}

	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
	public int FastEmaLength { get => _fastEmaLength.Value; set => _fastEmaLength.Value = value; }
	public int SlowEmaLength { get => _slowEmaLength.Value; set => _slowEmaLength.Value = value; }
	public int RsiLength { get => _rsiLength.Value; set => _rsiLength.Value = value; }
	public int AtrLength { get => _atrLength.Value; set => _atrLength.Value = value; }

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

		_prevFast = 0; _prevSlow = 0; _entryPrice = 0;
	}

		protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		_prevFast = 0; _prevSlow = 0; _entryPrice = 0;
		var fastEma = new ExponentialMovingAverage { Length = FastEmaLength };
		var slowEma = new ExponentialMovingAverage { Length = SlowEmaLength };
		var rsi = new RelativeStrengthIndex { Length = RsiLength };
		var atr = new AverageTrueRange { Length = AtrLength };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fastEma, slowEma, rsi, atr, ProcessCandle).Start();
		var area = CreateChartArea();
		if (area != null) { DrawCandles(area, subscription); DrawIndicator(area, fastEma); DrawIndicator(area, slowEma); DrawOwnTrades(area); }
	}

	private void ProcessCandle(ICandleMessage candle, decimal fastVal, decimal slowVal, decimal rsiVal, decimal atrVal)
	{
		if (candle.State != CandleStates.Finished) return;
		if (_prevFast == 0 || _prevSlow == 0 || atrVal <= 0) { _prevFast = fastVal; _prevSlow = slowVal; return; }
		var close = candle.ClosePrice;

		if (Position > 0)
		{
			if ((fastVal < slowVal && _prevFast >= _prevSlow) || close <= _entryPrice - atrVal * 2m) { SellMarket(); _entryPrice = 0; }
		}
		else if (Position < 0)
		{
			if ((fastVal > slowVal && _prevFast <= _prevSlow) || close >= _entryPrice + atrVal * 2m) { BuyMarket(); _entryPrice = 0; }
		}

		if (Position == 0)
		{
			if (fastVal > slowVal && _prevFast <= _prevSlow && rsiVal > 50) { _entryPrice = close; BuyMarket(); }
			else if (fastVal < slowVal && _prevFast >= _prevSlow && rsiVal < 50) { _entryPrice = close; SellMarket(); }
		}
		_prevFast = fastVal; _prevSlow = slowVal;
	}
}