GitHub で見る
ミッションインポッシブル パワーツーオープン戦略
概要
この戦略は、MetaTrader エキスパート アドバイザー「ミッション インポッシブル パワー ツー オープン」の StockSharp 移植です。最も最近完了したローソク足の方向を監視し、その方向に新しい取引バスケットを開きます。価格がアクティブなバスケットに対して変動すると、この戦略は固定ピップグリッドに従って新しい平均エントリを追加します。新しい各エントリの量は、元の EA の power ベースのサイジング ルールを模倣し、バスケットの浮動損失に応じて増加します。バスケット全体が単一のテイクプロフィットとストップロスのレベルを共有するように、約定のたびにエグジットターゲットが再計算されます。
取引ロジック
- シグナル検出 – 終了したローソク足ごとに、戦略は前のローソク足の終値と始値を比較します。
- 前のローソク足が始値を上回って終了した場合、ロングシグナルがアクティブになります。
- オープンより下でクローズした場合、ショート信号がアクティブになります。
- 内側のバー (クローズとオープンが等しい) では、新しいバスケットは生成されません。
- 最初の取引を開始する – シグナルされた方向でアクティブなグリッドがない場合、ストラテジーは
BaseVolume サイズの成行注文を出します。
- 平均グリッド – バスケットが存在する場合、ストラテジーは最後に約定した価格と現在の終値との間の距離を測定し続けます。
- ロングの場合、価格が最後の約定より少なくとも
GridStepPips * PriceStep 下がった時点で新しいエントリーが追加されます。
- 空売りの場合、この戦略は価格が最後の約定から同じ距離だけ上昇するまで待ちます。
- それぞれの方向で
MaxTrades の塗りつぶしに達すると、グリッドは新しい位置の追加を停止します。
- ダイナミックボリューム – 新しい注文を送信する前に、ストラテジーはバスケットの含み損を計算し、それに
Power * 0.0001 を乗算し、その結果を BaseVolume に加算します。最終的なサイズは取引量ステップに四捨五入され、セキュリティ制限内に固定され、MaxVolume によって上限が設定されます。
- 出口管理 – 毎回の充填後に、戦略はバスケット全体の共有目標を再計算します。
- 単一のポジションでは、テイクプロフィットはエントリーから
TakeProfitFirstPips 離れており、ストップロスは反対方向の StopLossPips 離れています。
- 2 つ以上のポジションがある場合、両方のレベルはバスケットの出来高加重平均価格に固定され、ターゲット距離には
TakeProfitNextPips、保護には StopLossPips が使用されます。
- 価格がテイクプロフィットまたはストップロスのいずれかに触れると、その方向のすべてのポジションが市場でクローズされます。
- 独立したバスケット – 長いグリッドと短いグリッドは独立して追跡されます。この戦略は、交流信号が到着したときに両方を同時に保持できます。
パラメーター
| 名前 |
種類 |
デフォルト |
説明 |
BaseVolume |
decimal |
0.01 |
スケーリング前の新しいバスケットの最初の注文サイズ。 |
MaxVolume |
decimal |
2 |
四捨五入後の単一成行注文のハードキャップ。 |
Power |
decimal |
13 |
新規エントリーの追加量を計算する際に、浮動損失に適用される乗数。 |
StopLossPips |
int |
400 |
共有ストップロスに使用される価格ステップの距離。 |
TakeProfitFirstPips |
int |
15 |
バスケットの最初のエントリーのテイクプロフィット距離。 |
TakeProfitNextPips |
int |
7 |
平均バスケット (2 つ以上のエントリー) のテイクプロフィット距離。 |
GridStepPips |
int |
21 |
別の平均エントリーが許可されるまでの最小の逆方向の動き (価格ステップ単位)。 |
MaxTrades |
int |
16 |
方向ごとのグリッド取引の最大数。 |
CandleType |
DataType |
TimeSpan.FromMinutes(5).TimeFrame() |
信号の生成とバスケットの管理に使用されるキャンドル。 |
注意事項
- 注文量は常に商品の
VolumeStep に合わせられますが、取引板からこれらの制限が利用可能な場合は、証券の MinVolume および MaxVolume によって制限されます。
- ロングステートマシンとショートステートマシンは完全に分離されているため、市場の方向性が急速に切り替わる場合でも、ヘッジされたバスケットを維持する戦略が可能です。
- 保護レベルは約定ごとに再計算され、最も近い
PriceStep に四捨五入され、MetaTrader バージョンで頻繁に実行されるテイクプロフィット修正ルーチンと一致します。
- インジケーターバッファは使用されません。すべての決定は、ソース EA と同様に、生のローソク足データとポートフォリオ情報に基づいています。
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Mission Impossible Power Two Open strategy: Candle direction with EMA trend filter.
/// Buys on bullish candle when above EMA, sells on bearish candle when below EMA.
/// </summary>
public class MissionImpossiblePowerTwoOpenStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaPeriod;
private bool _wasBullishSignal;
private bool _hasPrevSignal;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public MissionImpossiblePowerTwoOpenStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_emaPeriod = Param(nameof(EmaPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA trend filter period", "Indicators");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_wasBullishSignal = false;
_hasPrevSignal = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_wasBullishSignal = false;
_hasPrevSignal = false;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal emaValue)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
var open = candle.OpenPrice;
var bullish = close > open;
var bearish = close < open;
var bullishSignal = bullish && close > emaValue;
var bearishSignal = bearish && close < emaValue;
var crossedUp = bullishSignal && (!_hasPrevSignal || !_wasBullishSignal);
var crossedDown = bearishSignal && (!_hasPrevSignal || _wasBullishSignal);
if (crossedUp && Position <= 0)
BuyMarket();
else if (crossedDown && Position >= 0)
SellMarket();
if (bullishSignal || bearishSignal)
{
_wasBullishSignal = bullishSignal;
_hasPrevSignal = true;
}
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class mission_impossible_power_two_open_strategy(Strategy):
def __init__(self):
super(mission_impossible_power_two_open_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(60)))
self._ema_period = self.Param("EmaPeriod", 50)
self._was_bullish_signal = False
self._has_prev_signal = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def EmaPeriod(self):
return self._ema_period.Value
@EmaPeriod.setter
def EmaPeriod(self, value):
self._ema_period.Value = value
def OnReseted(self):
super(mission_impossible_power_two_open_strategy, self).OnReseted()
self._was_bullish_signal = False
self._has_prev_signal = False
def OnStarted2(self, time):
super(mission_impossible_power_two_open_strategy, self).OnStarted2(time)
self._was_bullish_signal = False
self._has_prev_signal = False
ema = ExponentialMovingAverage()
ema.Length = self.EmaPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, self._process_candle).Start()
def _process_candle(self, candle, ema_value):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
open_price = float(candle.OpenPrice)
ema_val = float(ema_value)
bullish = close > open_price
bearish = close < open_price
bullish_signal = bullish and close > ema_val
bearish_signal = bearish and close < ema_val
crossed_up = bullish_signal and (not self._has_prev_signal or not self._was_bullish_signal)
crossed_down = bearish_signal and (not self._has_prev_signal or self._was_bullish_signal)
if crossed_up and self.Position <= 0:
self.BuyMarket()
elif crossed_down and self.Position >= 0:
self.SellMarket()
if bullish_signal or bearish_signal:
self._was_bullish_signal = bullish_signal
self._has_prev_signal = True
def CreateClone(self):
return mission_impossible_power_two_open_strategy()