GitHub で見る
Bands 待機注文ブレイクアウト戦略
この戦略はStockSharpの高レベルAPIの上にMetaTraderエキスパートアドバイザー「Bands 2」を複製します。完成したローソク足を監視し、現在時刻が設定された取引ウィンドウ内にあり、価格がボリンジャーチャネル内で取引されていることを確認します。これらの条件が満たされると、ボリンジャーエンベロープの周りに3つの買いストップと3つの売りストップの対称グリッドを配置します。各注文は独自のストップロスとテイクプロフィット距離を持ち、いずれかの約定が他の待機注文を削除します。
このアプローチはボリンジャーバンドからのブレイクアウトのために設計されています。ストップロスの参照は反対側のバンドまたは中央移動平均の間で切り替えることができます。個別のトレーリングストップモジュールが、ポジションが設定可能なステップで利益方向に動いたときに保護ストップを継続的に引き締めます。
詳細
- 市場データ: StockSharpを通じて提供される任意のインストゥルメント/ローソク足タイプで動作します。
- 取引時間:
HourStart/HourEndを使用して注文の配置を制限します。注文はそのウィンドウ内の完成した各ローソク足で更新されます。
- エントリーロジック:
- シフトされた上部と下部のボリンジャーバンドの間に厳密に収まる終値の完成したローソク足を待ちます。
- 前のバーの残りの待機注文を削除し、上部バンドの上に3つの買いストップ、下部バンドの下に3つの売りストップを配置します。
- 各ティアはtickに変換された
StepPipsで区切られています。
- ストップロスモード:
- BollingerBands: ストップロスはエントリー注文と同じステップ距離でオフセットされた反対のバンドを使用します。
- MovingAverage: ストップロスは移動平均値プラス/マイナスのステップ距離を使用します(設定された適用価格と方法を使用)。
- None: 初期ストップは設定されません;トレーリングストップは後で有効化できます。
- テイクプロフィットロジック:
- 最初のレベルは買いと売り注文の両方に
FirstTakeProfitPipsを使用します。
- 2番目と3番目の買い注文は
Second/Thirdテイクプロフィット距離を使用し、売り注文は元のMQLスクリプトの動作に従い常に最初のテイクプロフィット距離を再使用します。
- 注文管理:
- 待機注文が約定すると、戦略は他のすべてのエントリー注文をキャンセルし、約定したボリュームのために市場から独立した保護注文(ストップ + リミット)を作成します。
- トレーリングモジュールは、エントリーから
TrailingStopPips + TrailingStepPips価格が動いたときにストップ注文を市場に向けて移動させます。
- ポジションがフラットになったときに保護ストップ/リミット注文が自動的にキャンセルされます。
- 価格正規化: すべての価格レベルはインストゥルメントのティックサイズに丸められ、ポイント対ピップ変換はオリジナルの3/5桁の処理を模倣します。
パラメーター
| パラメーター |
説明 |
OrderVolume |
各待機注文のボリューム(6つすべての注文で同じボリューム)。 |
CandleType |
インジケーター計算に使用するタイムフレーム/データタイプ。 |
HourStart, HourEnd |
新しい待機注文の配置を許可する時間(0-24)。HourEndはHourStartより大きくなければなりません。 |
StopLossModes |
初期ストップロスの配置参照(BollingerBands、MovingAverage、None)。 |
FirstTakeProfitPips, SecondTakeProfitPips, ThirdTakeProfitPips |
最初、2番目、3番目のエントリーの価格オフセットに変換されたテイクプロフィット距離(pips)。 |
TrailingStopPips, TrailingStepPips |
トレーリングストップ距離とストップが進む前に必要な追加ステップ。トレーリングを無効にするには0に設定。 |
StepPips |
連続する待機注文間の間隔(価格に変換)。 |
MaPeriod, MaShift, MaMethod, MaPriceType |
ボリンジャー入力に使用する移動平均設定、オプションでStopLossModesがMovingAverageのときのストップ配置にも使用。MaShiftはオリジナルEAの前方シフトをエミュレートします。 |
BandsPeriod, BandsShift, BandsDeviation, BandsPriceType |
ボリンジャーバンド設定(期間、シフト、偏差乗数、適用価格)。 |
動作概要
- 選択したタイムフレームの完成したローソク足にサブスクライブします。
- 取引ウィンドウ内の各完成したローソク足で、選択した適用価格を使用してシフトされたボリンジャーバンドと移動平均を計算します。
- ローソク足の終値がバンドチャネル内にあることを確認し、個別のストップとターゲットを持つチャネルエッジ周辺に買い/売りストップグリッドを配置します。
- 注文が約定したとき、残りのエントリー注文をキャンセルし、保護ストップ/リミット注文を提出し、設定されたパラメーターに従ってトレーリングを開始します。
- ポジションが終了したときに保護注文を閉じ、次のブレイクアウト機会に備えます。
namespace StockSharp.Samples.Strategies;
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Bands Pending Breakout strategy (simplified).
/// Buys when price closes above the upper Bollinger Band.
/// Sells when price closes below the lower Bollinger Band.
/// </summary>
public class BandsPendingBreakoutStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _bbPeriod;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int BbPeriod
{
get => _bbPeriod.Value;
set => _bbPeriod.Value = value;
}
public BandsPendingBreakoutStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Source candles", "General");
_bbPeriod = Param(nameof(BbPeriod), 15)
.SetGreaterThanZero()
.SetDisplay("BB Period", "Bollinger Bands period", "Indicators");
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var bb = new BollingerBands { Length = BbPeriod, Width = 1m };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(bb, (ICandleMessage candle, IIndicatorValue bbValue) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var bbTyped = (BollingerBandsValue)bbValue;
if (bbTyped.UpBand is not decimal upper || bbTyped.LowBand is not decimal lower)
return;
// Buy on breakout above upper band
if (candle.ClosePrice > upper && Position <= 0)
{
BuyMarket();
}
// Sell on breakdown below lower band
else if (candle.ClosePrice < lower && Position >= 0)
{
SellMarket();
}
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, bb);
DrawOwnTrades(area);
}
}
}
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 BollingerBands
from StockSharp.Algo.Strategies import Strategy
class bands_pending_breakout_strategy(Strategy):
def __init__(self):
super(bands_pending_breakout_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Source candles", "General")
self._bb_period = self.Param("BbPeriod", 15) \
.SetDisplay("BB Period", "Bollinger Bands period", "Indicators")
@property
def candle_type(self):
return self._candle_type.Value
@candle_type.setter
def candle_type(self, value):
self._candle_type.Value = value
@property
def bb_period(self):
return self._bb_period.Value
@bb_period.setter
def bb_period(self, value):
self._bb_period.Value = value
def OnStarted2(self, time):
super(bands_pending_breakout_strategy, self).OnStarted2(time)
self._bb = BollingerBands()
self._bb.Length = self.bb_period
self._bb.Width = 1.0
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(self._bb, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, self._bb)
self.DrawOwnTrades(area)
def OnProcess(self, candle, bb_value):
if candle.State != CandleStates.Finished:
return
upper = bb_value.UpBand
lower = bb_value.LowBand
if upper is None or lower is None:
return
if candle.ClosePrice > upper and self.Position <= 0:
self.BuyMarket()
elif candle.ClosePrice < lower and self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return bands_pending_breakout_strategy()