GitHub で見る
日時指定注文
この戦略は、MetaTrader エキスパート 「エキスパート アドバイザーの特定の日時」 を複製します。
スケジュールされたタイムスタンプで買い注文および/または売り注文を出し、オプションで別のタイムスタンプですべてのエクスポージャーを削除します。
StockSharp バージョンでは、オプションのトレーリング ストップや損益分岐点など、元のリスク管理動作が維持されます。
コアロジック
スケジュール設定
OpenTime – 注文が作成された瞬間。
CloseTime – ポジションがフラットになり未決注文を削除できる瞬間。
どちらのチェックも 1 分間のウィンドウを受け入れ、MT4 コードで使用される TimeToString(..., TIME_MINUTES) 比較と一致します。
注文の発注
OrderPlacement は、成行注文、逆指値注文、指値注文のいずれかを選択します。
OpenBuyOrders / OpenSellOrders は希望のルートを有効にします。
OrderDistancePoints は、未決注文の価格をポイント (pips) 数でオフセットします。
PendingExpireMinutes は、有効期間が終了すると保留中の注文を自動的にキャンセルします。
ボリューム管理
LotSizing = Manual は固定の ManualVolume を送信します。
LotSizing = Automatic は、現在のポートフォリオ値と商品契約サイズから出来高を計算します。
volume = (portfolio / contractSize) * RiskFactor。
結果は Security.VolumeStep に揃えられ、利用可能な場合は MinVolume/MaxVolume の間に固定されます。
保護ロジック
StopLossPoints と TakeProfitPoints は、商品のピップ サイズを使用して、元のポイントベースの距離を絶対価格に変換します。
TrailingStopEnabled + TrailingStepPoints と BreakEvenEnabled は、入札/売値の更新をトリガーとして使用して、MQL スクリプトとまったく同じように保護ストップを移動します。
- ストップロスまたはテイクプロフィット条件に達すると、ストップを新しい価格に変更する MT4 の動作を反映して、ポジションは成行注文でクローズされます。
終了フェーズ
CloseOwnOrders または CloseAllOrders が有効な場合、戦略はクローズ ウィンドウ内のオープン ポジションを終了します。
DeletePendingOrders は、残りの未決注文をすべて同時に削除します。
パラメーター
| 名前 |
説明 |
OpenTime, CloseTime |
マーケットに出入りするための UTC タイムスタンプ。 |
OrderPlacement |
成行注文、逆指値注文、または指値注文の発注。 |
OpenBuyOrders, OpenSellOrders |
アクティベートする手順。 |
TakeProfitPoints, StopLossPoints |
保護距離はポイントで表されます (0 は無効になります)。 |
TrailingStopEnabled, TrailingStepPoints |
トレーリングストップを有効にし、移動する前の最小前進量を定義します。 |
BreakEvenEnabled, BreakEvenAfterPoints |
利益がしきい値を超えたら、ストップを損益分岐点にシフトします。 |
OrderDistancePoints |
未決注文に使用されるオフセット。 |
PendingExpireMinutes |
未決注文の有効期限ウィンドウ。 |
LotSizing |
手動または自動のボリュームサイジング。 |
RiskFactor, ManualVolume |
サイズ設定モードの入力。 |
CloseOwnOrders, CloseAllOrders, DeletePendingOrders |
最後にポジションと未決注文をどのようにクローズするかを制御します。 |
注意事項
- このクラスは、プロジェクト ガイドラインの要求に従ってタブ インデントを持つ
StockSharp.Samples.Strategies 名前空間に存在します。
- レベル 1 データは、MQL バージョンの買値/売値に依存するロジック (トレーリング ストップ、未決注文の配置) を再現するために使用されます。
- StockSharp はすでにストラテジー注文を分離しているため、MT4 からの
MagicNumber 設定は必要ありません。
使用法
AlgoTrading.sln を介してプロジェクトをコンパイルし、戦略をセキュリティ/ポートフォリオのペアに添付します。
- 必要に応じて、スケジュール、注文タイプ、リスクパラメータを調整します。
OpenTime より前に戦略を開始してください。注文はウィンドウが開始されると自動的に送信されます。
- 自動平坦化ステップを開始する場合は、
CloseTime が終わるまで戦略を実行し続けます。
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Specific Day Time strategy: SMA crossover with time filter.
/// Trades only during specific hours, using fast/slow SMA crossover.
/// </summary>
public class SpecificDayTimeStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _tradeHour;
private readonly StrategyParam<int> _cooldownBars;
private int _cooldown;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public int TradeHour { get => _tradeHour.Value; set => _tradeHour.Value = value; }
public int CooldownBars { get => _cooldownBars.Value; set => _cooldownBars.Value = value; }
public SpecificDayTimeStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 8)
.SetGreaterThanZero()
.SetDisplay("Fast SMA", "Fast SMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 21)
.SetGreaterThanZero()
.SetDisplay("Slow SMA", "Slow SMA period", "Indicators");
_tradeHour = Param(nameof(TradeHour), 12)
.SetDisplay("Trade Hour", "Hour when entries are allowed", "Trading")
.SetRange(0, 23);
_cooldownBars = Param(nameof(CooldownBars), 8)
.SetGreaterThanZero()
.SetDisplay("Cooldown Bars", "Bars to wait between orders", "Trading");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_cooldown = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_cooldown = 0;
var fast = new SimpleMovingAverage { Length = FastPeriod };
var slow = new SimpleMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fastValue, decimal slowValue)
{
if (candle.State != CandleStates.Finished) return;
if (_cooldown > 0)
_cooldown--;
var bullishTrend = fastValue > slowValue;
var bearishTrend = fastValue < slowValue;
if (_cooldown == 0 && candle.OpenTime.Hour == TradeHour)
{
if (bullishTrend && Position <= 0)
{
BuyMarket();
_cooldown = CooldownBars;
}
else if (bearishTrend && Position >= 0)
{
SellMarket();
_cooldown = CooldownBars;
}
}
else if (_cooldown == 0)
{
if (Position > 0 && bearishTrend)
{
SellMarket();
_cooldown = CooldownBars;
}
else if (Position < 0 && bullishTrend)
{
BuyMarket();
_cooldown = CooldownBars;
}
}
}
}
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
from StockSharp.Algo.Strategies import Strategy
class specific_day_time_strategy(Strategy):
def __init__(self):
super(specific_day_time_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30)))
self._fast_period = self.Param("FastPeriod", 8)
self._slow_period = self.Param("SlowPeriod", 21)
self._trade_hour = self.Param("TradeHour", 12)
self._cooldown_bars = self.Param("CooldownBars", 8)
self._cooldown = 0
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def FastPeriod(self):
return self._fast_period.Value
@FastPeriod.setter
def FastPeriod(self, value):
self._fast_period.Value = value
@property
def SlowPeriod(self):
return self._slow_period.Value
@SlowPeriod.setter
def SlowPeriod(self, value):
self._slow_period.Value = value
@property
def TradeHour(self):
return self._trade_hour.Value
@TradeHour.setter
def TradeHour(self, value):
self._trade_hour.Value = value
@property
def CooldownBars(self):
return self._cooldown_bars.Value
@CooldownBars.setter
def CooldownBars(self, value):
self._cooldown_bars.Value = value
def OnReseted(self):
super(specific_day_time_strategy, self).OnReseted()
self._cooldown = 0
def OnStarted2(self, time):
super(specific_day_time_strategy, self).OnStarted2(time)
self._cooldown = 0
fast = SimpleMovingAverage()
fast.Length = self.FastPeriod
slow = SimpleMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast, slow, self._process_candle).Start()
def _process_candle(self, candle, fast_value, slow_value):
if candle.State != CandleStates.Finished:
return
if self._cooldown > 0:
self._cooldown -= 1
bullish_trend = float(fast_value) > float(slow_value)
bearish_trend = float(fast_value) < float(slow_value)
if self._cooldown == 0 and candle.OpenTime.Hour == self.TradeHour:
if bullish_trend and self.Position <= 0:
self.BuyMarket()
self._cooldown = self.CooldownBars
elif bearish_trend and self.Position >= 0:
self.SellMarket()
self._cooldown = self.CooldownBars
elif self._cooldown == 0:
if self.Position > 0 and bearish_trend:
self.SellMarket()
self._cooldown = self.CooldownBars
elif self.Position < 0 and bullish_trend:
self.BuyMarket()
self._cooldown = self.CooldownBars
def CreateClone(self):
return specific_day_time_strategy()