GitHub で見る
SpaceX、ストップロス・テイクプロフィット・ボタン戦略を削除
概要
この戦略は、元の MetaTrader パネル SpaceX_Delete_StopLoss_TakeProfit_button.mq5 の 「DELETE SL_TP」 ボタンを再現します。これは、現在のポートフォリオをスキャンし、オープンポジションに属するすべてのアクティブな保護的なストップロスまたはテイクプロフィット注文をキャンセルするユーティリティヘルパーとして設計されています。この変換は、StockSharp の高レベル API をターゲットにしており、各チケットを手動で開かずに保護ブラケットを削除する便利な方法を提供します。
この戦略は、それ自体でポジションをオープンまたはクローズしません。すでに開かれている取引を検査し、指示があれば保護命令を解除するだけです。これは、ポジションを手動または他の自動システムで管理しているが、すべての逆指値注文と利益確定注文をクリアするためのクイック パニック ボタンを必要とするトレーダーに適しています。
オリジナルのエキスパートアドバイザー
MetaTrader バージョンでは、DELETE SL_TP ボタンを備えた単一のダイアログ ウィンドウが描画されます。ボタンが押されるたびに、エキスパートはすべてのオープンポジションを反復処理し、ストップロスとテイクプロフィットの値をゼロにして PositionModify を呼び出します。その結果、すべての保護レベルがポジションから切り離されますが、ポジションボリュームはそのまま残ります。
ソースコードの主な動作:
- 市場へのエントリーやエグジットは発生しません。
- 端末内のすべてのシンボルはフィルタリングなしで処理されます。
- ストップロスとテイクプロフィットの値のみが削除されます。注文コメントとマジックナンバーはそのまま残ります。
- アクションは GUI ボタンによってのみトリガーされます。
StockSharpの実装
StockSharp 変換により、保護命令の解除に重点を置いた動作が維持されます。 GUI ダイアログの代わりに、アクションは、StockSharp UI またはコードから切り替えることができる戦略パラメーターによって駆動されます。この戦略は、注文のストップまたはテイクプロフィット情報を公開する任意のブローカーアダプターで機能します。
次の 2 つの実行モードがサポートされています。
- 開始時の自動実行 – オプション。有効にすると、戦略は実行開始直後に保護命令を削除します。
- 手動コマンド – 元のボタンを模倣するブール値パラメータ。パラメータを
true に設定すると、次のタイマー ティックでクリーンアップがスケジュールされ、その後フラグが false にリセットされます。
変換では、ストップロス、テイクプロフィット、またはその他の条件付きプロテクション注文として識別されるすべての有効な注文に対して CancelOrder を呼び出すことにより、プロテクション注文がキャンセルされます。ポジションボリュームには一切触れません。
パラメーター
| 名前 |
説明 |
デフォルト |
開始時に実行 (ApplyOnStart) |
true の場合、戦略は開始直後に保護命令を解除します。 |
true |
すべての証券 (AffectAllSecurities) |
すべてのポートフォリオのポジションを処理します。 false の場合、戦略のセキュリティのみが考慮されます。 |
true |
リクエストの削除 (DeleteRequest) |
MetaTrader ボタンをエミュレートする手動トリガー。 1 回限りの削除を実行するには、これを true に切り替えます。自動的にリセットされます。 |
false |
ポーリング間隔 (秒) (PollingIntervalSeconds) |
手動トリガーのポーリングに使用されるタイマー間隔 (秒単位)。 Run On Start が無効になっている場合、タイマーは削除リクエストも実行します。 |
1 |
仕組み
- 開始時に、戦略はポーリング間隔を検証し、N 秒ごとに起動するタイマーを開始します。
- 開始時に実行 が有効になっている場合は、即時にクリーンアップが実行されます。
- タイマーが刻まれるたびに、削除リクエスト フラグがチェックされます。フラグが
true の場合、ストラテジーは設定された範囲内でオープン ポジションを持つ証券を収集し、それらの商品に対するすべての保護注文をキャンセルします。
- 実行後、手動フラグは
false にリセットされ、アクションがリクエストごとに 1 回だけ実行されるようになります。
秘密保持命令の特定
次の条件のいずれかが満たされる場合、注文は保護されたものとして扱われます。
- 注文タイプは、
Stop、TakeProfit、または Conditional です。
- ストップ価格、利食い価格、または NULL 以外の注文条件が存在します。
この保守的な定義では、最も一般的なアダプターがカバーされています。コネクタが停止管理にカスタム注文タイプまたは条件を使用する場合は、それに応じて検出ロジックを拡張します。
使用のヒント
- オープン取引を管理するコネクタに戦略を接続します。管理したいすべてのポジションが設定されたポートフォリオに表示されていることを確認してください。
- 削除リクエスト チェックボックスを切り替えて、Hydra またはターミナルのパラメータ グリッドから削除リクエストをトリガーします。
- このユーティリティを他の方法と組み合わせて、新しい保護ブラケットを適用する前に一時的に保護ブラケットを取り外します。
- ボタンの応答性を高めるには、ポーリング間隔を短く (デフォルトでは 1 秒) にしてください。タイマーのアクティビティを減らしたい場合は、値を増やします。
オリジナルの EA との違い
- MetaTrader ボタンは、チャート ダイアログを介して即座に機能します。 StockSharp では、アクションはタイマーによって監視されるパラメータとして公開されます。
- 保護命令は、ポジションオブジェクトを変更する代わりにキャンセルされます。ストップロスとテイクプロフィットのレベルはインラインのポジションプロパティではなく個別の注文として表されるため、これは StockSharp 内での自然なアプローチです。
- オプションのスコープ制御を使用すると、接続されたセキュリティに操作を制限できます。これは、元のエキスパートと比較してさらに便利です。
制限事項
- この戦略では、アダプターがストップロス注文と利食い注文をアクティブな注文として公開する必要があります。ブローカーが注文として表されないサーバー側の保護レベルを使用している場合、注文をキャンセルできない可能性があります。
- GUI ダイアログは作成されません。制御は完全に戦略パラメーターまたはプログラムによるアクセスを介して実行されます。
- このユーティリティは保護レベルを再作成しません。それらを削除するだけです。
テスト
この戦略には、複雑な計算を行わずにユーティリティ関数が実行されるため、専用の自動テストは含まれていません。手動テストは、サンプル ポジションをオープンし、戦略をアタッチし、各トリガー後にすべての保護命令がキャンセルされることを確認することによって実行できます。
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// SpaceX Delete SL/TP strategy: Standard Deviation breakout.
/// Buys when price breaks above upper StdDev band, sells on break below lower.
/// </summary>
public class SpaceXDeleteStopLossTakeProfitButtonStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _smaPeriod;
private readonly StrategyParam<int> _stdDevPeriod;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int SmaPeriod { get => _smaPeriod.Value; set => _smaPeriod.Value = value; }
public int StdDevPeriod { get => _stdDevPeriod.Value; set => _stdDevPeriod.Value = value; }
public SpaceXDeleteStopLossTakeProfitButtonStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_smaPeriod = Param(nameof(SmaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("SMA Period", "SMA period for baseline", "Indicators");
_stdDevPeriod = Param(nameof(StdDevPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("StdDev Period", "Standard Deviation period", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sma = new SimpleMovingAverage { Length = SmaPeriod };
var stdDev = new StandardDeviation { Length = StdDevPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(sma, stdDev, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal smaValue, decimal stdDevValue)
{
if (candle.State != CandleStates.Finished) return;
var upper = smaValue + 2 * stdDevValue;
var lower = smaValue - 2 * stdDevValue;
if (candle.ClosePrice > upper && Position <= 0)
BuyMarket();
else if (candle.ClosePrice < lower && Position >= 0)
SellMarket();
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import SimpleMovingAverage, StandardDeviation
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
from indicator_extensions import *
class space_x_delete_stop_loss_take_profit_button_strategy(Strategy):
def __init__(self):
super(space_x_delete_stop_loss_take_profit_button_strategy, self).__init__()
self._sma_period = self.Param("SmaPeriod", 20).SetGreaterThanZero().SetDisplay("SMA Period", "SMA period for baseline", "Indicators")
self._std_period = self.Param("StdDevPeriod", 20).SetGreaterThanZero().SetDisplay("StdDev Period", "Standard Deviation period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Candle timeframe", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnStarted2(self, time):
super(space_x_delete_stop_loss_take_profit_button_strategy, self).OnStarted2(time)
sma = SimpleMovingAverage()
sma.Length = self._sma_period.Value
std = StandardDeviation()
std.Length = self._std_period.Value
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(sma, std, self.OnProcess).Start()
def OnProcess(self, candle, sma_val, std_val):
if candle.State != CandleStates.Finished:
return
upper = sma_val + 2 * std_val
lower = sma_val - 2 * std_val
close = float(candle.ClosePrice)
if close > upper and self.Position <= 0:
self.BuyMarket()
elif close < lower and self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return space_x_delete_stop_loss_take_profit_button_strategy()