GitHub で見る
簡単ロボット戦略
概要
Easy Robot は、完了した 1 時間ごとのローソク足ごとに 1 回取引する、勢いに従うエキスパートアドバイザーです。前のローソク足が強気で閉じると、戦略は新しいロングポジションを開きます。弱気で閉じるとショートが始まります。常に 1 つのポジションのみをアクティブにでき、元の MetaTrader 4 ロジックを完全にミラーリングします。
取引ルール
- CandleType パラメーターで選択された時間ごとのローソク足タイプをサブスクライブします (デフォルトは H1)。
- ローソク足が完成したら、終値と始値を比較します。
- クローズ > オープン: オープンなポジションがない場合は成行買い注文を送信します。
- クローズ < オープン: 横ばいの場合は成行売り注文を送信します。
- ポジション サイズは、デフォルト 0.01 ロットの
CheckVolumeValue に依存する MQL バージョンとまったく同じように、戦略 Volume プロパティを使用します。
- ストップロスとテイクプロフィットのレベルは、期間 AtrPeriod (デフォルトは 14) の 平均トゥルー レンジ インジケーターに依存します。
- 停止距離 =
ATR * StopFactor。
- 距離 =
ATR * TakeFactor を取得します。
- 両方の距離は最小ティック/ピップス距離によって正規化されるため、ブローカーが許可するよりも近くに保護注文が発注されることはありません。
- 保護注文は、成行注文の直後に
SetStopLoss および SetTakeProfit を通じて登録され、sl および tp パラメーターを備えた OrderSend と同じ動作を提供します。
- UseTrailingStop が true の場合、オプションのトレーリングがアクティブになります。取引で TrailingStartPips の利益 (MetaTrader ピップ、つまり 3/5 小数点の相場に調整されたポイント) が蓄積された後、ストップは TrailingStepPips だけ近づき、新たな利益の極値に達した場合にのみさらに押し上げられます。トレーリングは無効な変更を避けるためにブローカーの最小停止距離を尊重します。
- ストップ計算の見積りでは、可能な場合は最高の買値/売値が使用され、元の
Bid/Ask 参照と一致する、最後の価格またはローソク足の終値に戻ります。
パラメーター
| 名前 |
デフォルト |
説明 |
TakeFactor |
4.2 |
利食い距離の ATR 乗数 (MQL の TakeFactor 入力にマップされます)。 |
StopFactor |
4.9 |
ストップロス距離の ATR 乗数 (StopFactor にマッピング)。 |
UseTrailingStop |
本当の |
MetaTrader スタイルの末尾 (UseTstop) を有効にします。 |
TrailingStartPips |
40 |
トレーリングが開始されるまでのピップ単位の利益 (Tstart)。 |
TrailingStepPips |
19 |
末尾の更新時に適用される PIP ステップ (Tstep)。 |
AtrPeriod |
14 |
ボラティリティサイジングの計算期間は ATR です。 |
CandleType |
H1 |
信号と ATR 入力に使用されるキャンドル シリーズ。 |
注意事項
- この戦略は、ポジションがゼロに戻るたびに保存されたエントリー価格とストップ価格をリセットし、次のシグナルに向けてクリーンな状態を保証します。
- 最小停止距離は、商品のピップサイズ (またはピップサイズが利用できない場合は価格ステップ) によって推定されます。これにより、MQL インクルード ファイルから
SC ヘルパーが再現されます。
StartProtection() は開始時に 1 回呼び出されるため、プラットフォームは必要に応じて非常口を管理できます。
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Easy Robot strategy: simple EMA + RSI trend following.
/// Buys when close above EMA and RSI above 50.
/// Sells when close below EMA and RSI below 50.
/// </summary>
public class EasyRobotStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<int> _rsiPeriod;
private bool _wasBullish;
private bool _hasPrevSignal;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public EasyRobotStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_emaPeriod = Param(nameof(EmaPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA period", "Indicators");
_rsiPeriod = Param(nameof(RsiPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("RSI Period", "RSI period", "Indicators");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_wasBullish = false;
_hasPrevSignal = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrevSignal = false;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, rsi, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal ema, decimal rsi)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
var isBullish = close > ema && rsi > 50;
if (_hasPrevSignal && isBullish != _wasBullish)
{
if (isBullish && Position <= 0)
BuyMarket();
else if (!isBullish && close < ema && rsi < 50 && Position >= 0)
SellMarket();
}
_wasBullish = isBullish;
_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, RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class easy_robot_strategy(Strategy):
def __init__(self):
super(easy_robot_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 50) \
.SetDisplay("EMA Period", "EMA period", "Indicators")
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI period", "Indicators")
self._ema = None
self._rsi = None
self._was_bullish = False
self._has_prev_signal = False
@property
def ema_period(self):
return self._ema_period.Value
@property
def rsi_period(self):
return self._rsi_period.Value
def OnReseted(self):
super(easy_robot_strategy, self).OnReseted()
self._ema = None
self._rsi = None
self._was_bullish = False
self._has_prev_signal = False
def OnStarted2(self, time):
super(easy_robot_strategy, self).OnStarted2(time)
self._ema = ExponentialMovingAverage()
self._ema.Length = self.ema_period
self._rsi = RelativeStrengthIndex()
self._rsi.Length = self.rsi_period
self._has_prev_signal = False
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromMinutes(30)))
subscription.Bind(self._ema, self._rsi, self._process_candle)
subscription.Start()
def _process_candle(self, candle, ema_value, rsi_value):
if candle.State != CandleStates.Finished:
return
if not self._ema.IsFormed or not self._rsi.IsFormed:
return
close = float(candle.ClosePrice)
ema_val = float(ema_value)
rsi_val = float(rsi_value)
is_bullish = close > ema_val and rsi_val > 50.0
if self._has_prev_signal and is_bullish != self._was_bullish:
if is_bullish and self.Position <= 0:
self.BuyMarket()
elif not is_bullish and close < ema_val and rsi_val < 50.0 and self.Position >= 0:
self.SellMarket()
self._was_bullish = is_bullish
self._has_prev_signal = True
def CreateClone(self):
return easy_robot_strategy()