GitHub で見る
プラン X ブレイクアウト戦略
プラン X ブレイクアウト戦略は、ピーター イングラムによる MetaTrader エキスパート アドバイザー「プラン X」を再現しています。ロンドンの午前中のセッションに焦点を当て、価格が基準ローソクから離れるのを待ってからエントリーします。一度にオープンできるネット ポジションは 1 つだけであり、リスクは有利に推移する取引の背後にあるピップベースのストップを通じて制御されます。
取引ロジック
セッションアンカー
- この戦略は 15 分足のローソク足を監視します。
- 設定されたセッション開始時間 (デフォルトは 11:00) に、そのローソク足の終値を記録します。この終値は残りのセッションのアンカー価格として機能します。
- 取引は、少なくとも 1 つの追加のローソク足が閉じた後、セッション終了時間 (デフォルトは 15:00) 前にのみ考慮されます。
エントリー条件
- ロング: 最後に終了したローソク足がアンカーの終値を
LongTargetPips (デフォルト 25 ピップス) 以上上で閉じ、ポジションが開いていない場合。
- ショート: 最後に終了したローソク足がアンカーのクローズよりも
ShortTargetPips (デフォルト 20 ピップス) 以上下でクローズし、オープンなポジションがない場合。
- すべての比較は、商品のティック サイズから派生したピップ単位で行われます。
ポジション管理
InitialStopPips (デフォルトは 25 ピップス) に等しい固定の初期ストップロスは、エントリー価格に対して設定されます。
- トレードが少なくとも
TrailTriggerPips (デフォルトは 10 ピップス) を獲得すると、ストップはトレーリング ストップに変換されます。
- 価格がさらに
TrailTriggerPips 進むたびに、ストップは収益性の高い方向に TrailStepPips (デフォルトは 5 ピップス) だけ移動します。
- 価格がストップに達すると、ポジションは市場でクローズされます。
ボリューム
- 注文には
TradeVolume パラメータが使用されます (デフォルトは 0.1 ロット)。保障契約の規模に合わせて調整してください。
パラメーター
| 名前 |
説明 |
デフォルト |
TradeVolume |
エントリーとエグジットに使用される成行注文の量。 |
0.1 |
LongTargetPips |
ロングエントリーに必要なアンカー上のブレイクアウト距離。 |
25 |
ShortTargetPips |
ショートエントリーに必要なアンカー下のブレイクアウト距離。 |
20 |
InitialStopPips |
エントリー価格から保護ストップロスまでの距離。 |
25 |
TrailTriggerPips |
トレーリングストップが有効化または前進する前に必要な利益 (pips)。 |
10 |
TrailStepPips |
トレーリングストップが移動するたびに適用されるピップ増分。 |
5 |
SessionStartHour |
アンカーローソクの開始時間を示す 10 進数の時間 (例: 11.0、11.5)。 |
11.0 |
SessionEndHour |
10 進数の時間。それ以降は新しいエントリは取得されません。 SessionStartHour 以降である必要があります。 |
15.0 |
CandleType |
評価に使用したキャンドルシリーズ。デフォルトは 15 分足のローソク足です。 |
15分 |
注意事項
- ピップサイズは、商品の
PriceStep と小数精度に基づいて自動的に調整されます (小数点以下 3 桁または 5 桁には 10 倍の乗数が適用されます)。
- この戦略では、継続的な日中市場が予想されます。日次ギャップのある商品では、再アンカー動作が取引日ごとに発生します。
- StockSharp 戦略はネット ポジションを使用するため、変換では一度に 1 つのオープン方向のみが想定されます。これは、ヘッジがアクティブでない場合の元のエキスパートのデフォルトの動作を反映しています。
ファイル
CS/PlanXBreakoutStrategy.cs – StockSharp のプラン X ブレークアウト ロジックの C# 実装。
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Plan X Breakout strategy using highest high / lowest low channel breakout.
/// Buy when price breaks above the highest high of the lookback period.
/// Sell when price breaks below the lowest low of the lookback period.
/// </summary>
public class PlanXBreakoutStrategy : Strategy
{
private readonly StrategyParam<int> _lookback;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevHigh;
private decimal _prevLow;
private bool _hasPrev;
public int Lookback { get => _lookback.Value; set => _lookback.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public PlanXBreakoutStrategy()
{
_lookback = Param(nameof(Lookback), 20)
.SetDisplay("Lookback", "Channel lookback period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevHigh = 0m;
_prevLow = 0m;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var highestHigh = new Highest { Length = Lookback };
var lowestLow = new Lowest { Length = Lookback };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(highestHigh, lowestLow, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal highest, decimal lowest)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevHigh = highest;
_prevLow = lowest;
_hasPrev = true;
return;
}
// Breakout above previous highest high
if (Position <= 0 && candle.ClosePrice > _prevHigh)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Breakout below previous lowest low
else if (Position >= 0 && candle.ClosePrice < _prevLow)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevHigh = highest;
_prevLow = lowest;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Math
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class plan_x_breakout_strategy(Strategy):
"""Plan X Breakout strategy using highest high / lowest low channel breakout.
Buy when price breaks above the highest high of the lookback period.
Sell when price breaks below the lowest low of the lookback period."""
def __init__(self):
super(plan_x_breakout_strategy, self).__init__()
self._lookback = self.Param("Lookback", 20) \
.SetDisplay("Lookback", "Channel lookback period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_high = 0.0
self._prev_low = 0.0
self._has_prev = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def Lookback(self):
return self._lookback.Value
def OnReseted(self):
super(plan_x_breakout_strategy, self).OnReseted()
self._prev_high = 0.0
self._prev_low = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(plan_x_breakout_strategy, self).OnStarted2(time)
self._has_prev = False
highest = Highest()
highest.Length = self.Lookback
lowest = Lowest()
lowest.Length = self.Lookback
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(highest, lowest, self._process_candle).Start()
def _process_candle(self, candle, highest, lowest):
if candle.State != CandleStates.Finished:
return
high_val = float(highest)
low_val = float(lowest)
close = float(candle.ClosePrice)
if not self._has_prev:
self._prev_high = high_val
self._prev_low = low_val
self._has_prev = True
return
# Breakout above previous highest high
if self.Position <= 0 and close > self._prev_high:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Breakout below previous lowest low
elif self.Position >= 0 and close < self._prev_low:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_high = high_val
self._prev_low = low_val
def CreateClone(self):
return plan_x_breakout_strategy()