GitHub で見る
ノア 10 ピップス 2006 戦略
概要
- オリジナルの Noah10pips2006 MetaTrader 4 エキスパート アドバイザーからブレイクアウトおよびリバーサル ロジックを再作成します。
- 前のセッションの価格チャネルを構築し、中間点付近に逆指値注文を出します。
- 安全な利益のトレーリング、オプションの動的ポジションサイジング、および最初のポジションが決済された後のオプションの反転取引を適用します。
取引ロジック
- セッション範囲の計算
すべての新しい取引日の開始時に (構成されたタイムゾーン オフセットを適用した後)、ストラテジーは前のセッションの高値と安値を記録します。これらのレベルは以下の計算に使用されます。
- 高値と低値の中間点。
- 「パス」バッファは範囲の上下 20 ピップスに配置されます。
- 40 pips (範囲が 160 pips より大きい場合は範囲の 25%) を減算/加算して得られるエントリー チャネル。
- 最初の未決注文
市場が取引ウィンドウに入ると、戦略は最新の終値をチェックします。
- 終値が中間点と上部バッファーの間にある場合、売りストップが中間点に配置されます。
- 終値が下側バッファーと中間点の間にある場合、買いストップが中間点に配置されます。
注文を行う前に、範囲幅が設定された最小値を超える必要があります。
- 2 番目の未決注文
アクティブなストップ注文が 1 つだけ残っている場合、システムは対応するバッファ (買いストップの場合は上部バッファ、売りストップでは下部バッファ) に逆方向の注文を追加します。これは元の EA の動作を反映しており、範囲の両側でブレイクアウトするための戦略を準備します。
- ポジション管理
- エントリーが約定した後に保護的なストップロス注文と利食い注文が作成されます。
- 変動利益が安全なトリガーしきい値に達すると、設定された安全な利益を固定するためにストップロスが移動します。
- 安全なロックがアクティブな場合、オプションのトレーリングストップは指定された距離で価格を追跡し続けます。
- 毎日のシャットダウン
すべての未決注文とオープンポジションは、取引ウィンドウが終了するか金曜日のカットオフに達するとクローズされます。
- リバーサルトレード
最初に完了したポジションは逆方向の成行注文をトリガーすることができ、元のコードの「ストップ後のリバース」動作を再現します。利益確保の調整によってすでに利益が確定している場合、反転はスキップされます。
パラメーター
| パラメータ |
説明 |
CandleType |
計算とタイミングを制御するために使用されるキャンドル シリーズ。デフォルト: 1 時間のローソク足。 |
TimeZoneOffset |
毎日の計算の前にタイムスタンプを交換するために適用されるシフト (時間単位)。 |
StartHour, StartMinute |
シフトされたタイムゾーンでの取引ウィンドウの開始時間。 |
EndHour, EndMinute |
取引ウィンドウの終了時間。それ以降、新しいエントリは配置されません。 |
FridayEndHour |
ポジションが強制決済される金曜日の時間。 |
TradeFriday |
金曜日に新しいポジションをオープンすることを有効または無効にします。 |
StopLossPips, TakeProfitPips |
エントリー後に作成された保護注文の距離 (pips)。 |
TrailingStopPips |
利益確保ステップの後に使用されるトレーリングストップ距離。末尾を無効にするには 0 に設定します。 |
SecureProfitPips |
安全なトリガーが作動すると利益がロックされます。 |
TrailSecureProfitPips |
ストップを安全なレベルに移動する前に必要な利益しきい値。 |
MinimumRangePips |
注文を出すために必要なエントリーチャネルの最小幅。 |
StartYear, StartMonth |
この日付より古い市場データは無視してください。 |
MinVolume, MaxVolume |
計算された注文量に適用される境界。 |
MaximumRiskPercent |
動的サイジングが有効になっている場合に、取引ごとにリスクが生じるポートフォリオ値の割合。 |
FixedVolume |
true の場合、戦略はリスク モデルの代わりに Volume プロパティを使用します。 |
実用上の注意
- リスクベースのポジションサイジングモードが使用される場合、商品は有効な
PriceStep および StepPrice 値を提供する必要があります。
- トレーリング調整と利益確定調整は完了したローソク足に依存するため、バー内フィルは次の完了したローソク足で処理されます。
- この戦略は、トレーリング ロジックがストップ価格を更新するたびに、保護注文をキャンセルして置き換えます。
- タイムゾーンのオフセットが履歴データのソースと一致していることを確認してください。そうしないと、前日の範囲が元の MT4 エキスパートと異なる可能性があります。
変換に関する注意事項
- MT4 バージョンのビジュアル描画オブジェクトは省略されました。必要に応じて、提供されたレベルを使用するか、カスタム チャートの注釈を追加します。
- このアルゴリズムは、固定 20/40 ピップ バッファーを変換するときに 4 桁の外国為替相場を想定しています。さまざまな資産クラスのパラメータを調整します。
- 逆取引は現在の出来高モデルを使用して市場で実行され、反対の未決注文を削除した後の元の EA の動作と一致します。
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>
/// Noah 10 Pips 2006 - session breakout strategy.
/// Tracks the previous session's high/low range.
/// Buys on breakout above the midpoint, sells on breakout below.
/// Uses Highest/Lowest indicators as channel reference.
/// </summary>
public class Noah10Pips2006Strategy : Strategy
{
private readonly StrategyParam<int> _channelPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevHigh;
private decimal _prevLow;
private decimal _prevMid;
private decimal _prevClose;
private bool _hasPrev;
public int ChannelPeriod { get => _channelPeriod.Value; set => _channelPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Noah10Pips2006Strategy()
{
_channelPeriod = Param(nameof(ChannelPeriod), 24)
.SetDisplay("Channel Period", "Lookback for high/low channel", "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;
_prevMid = 0m;
_prevClose = 0m;
_hasPrev = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var highest = new Highest { Length = ChannelPeriod };
var lowest = new Lowest { Length = ChannelPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(highest, lowest, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal high, decimal low)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
var mid = (high + low) / 2m;
if (!_hasPrev)
{
_prevHigh = high;
_prevLow = low;
_prevMid = mid;
_prevClose = close;
_hasPrev = true;
return;
}
// Breakout above channel high - buy
if (_prevClose <= _prevHigh && close > high && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Breakout below channel low - sell
else if (_prevClose >= _prevLow && close < low && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
// Cross above midpoint from below - buy signal
else if (_prevClose <= _prevMid && close > mid && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Cross below midpoint from above - sell signal
else if (_prevClose >= _prevMid && close < mid && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevHigh = high;
_prevLow = low;
_prevMid = mid;
_prevClose = close;
}
}
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 noah10_pips2006_strategy(Strategy):
"""Session breakout strategy. Tracks channel high/low/midpoint.
Buys on breakout above channel high or cross above midpoint.
Sells on breakout below channel low or cross below midpoint."""
def __init__(self):
super(noah10_pips2006_strategy, self).__init__()
self._channel_period = self.Param("ChannelPeriod", 24) \
.SetDisplay("Channel Period", "Lookback for high/low channel", "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._prev_mid = 0.0
self._prev_close = 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 ChannelPeriod(self):
return self._channel_period.Value
def OnReseted(self):
super(noah10_pips2006_strategy, self).OnReseted()
self._prev_high = 0.0
self._prev_low = 0.0
self._prev_mid = 0.0
self._prev_close = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(noah10_pips2006_strategy, self).OnStarted2(time)
self._has_prev = False
highest = Highest()
highest.Length = self.ChannelPeriod
lowest = Lowest()
lowest.Length = self.ChannelPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(highest, lowest, self._process_candle).Start()
def _process_candle(self, candle, high, low):
if candle.State != CandleStates.Finished:
return
high_val = float(high)
low_val = float(low)
close = float(candle.ClosePrice)
mid = (high_val + low_val) / 2.0
if not self._has_prev:
self._prev_high = high_val
self._prev_low = low_val
self._prev_mid = mid
self._prev_close = close
self._has_prev = True
return
# Breakout above channel high - buy
if self._prev_close <= self._prev_high and close > high_val and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Breakout below channel low - sell
elif self._prev_close >= self._prev_low and close < low_val and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
# Cross above midpoint from below - buy
elif self._prev_close <= self._prev_mid and close > mid and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Cross below midpoint from above - sell
elif self._prev_close >= self._prev_mid and close < mid and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_high = high_val
self._prev_low = low_val
self._prev_mid = mid
self._prev_close = close
def CreateClone(self):
return noah10_pips2006_strategy()