GitHub で見る
外国為替収益システム戦略
この戦略は、StockSharp のハイレベル API 内に古典的な MetaTrader エキスパート アドバイザー「外国為替利益システム」を再現します。使用します
ローソク足中央値の 3 つの指数移動平均 (EMA 10、25、50) と Parabolic SAR フィルターを組み合わせたもの。の
この組み合わせは、Parabolic の間に高速平均が低速トレンドラインを横切った後に現れる短期間のモメンタムバーストを検出します。
SAR はすでに価格と同じ側に反転しています。
取引ロジック
- インジケータースタック
- 完成したローソク足から導出された中央価格はすべてのインジケーターを駆動し、結果が元の MetaTrader "PRICE_MEDIAN" と一致するようにします。
入力。
- 高速な EMA (長さ 10) は、短期的な運動量の変化に素早く反応します。
- 中程度の EMA (長さ 25) と低速の EMA (長さ 50) は、方向のバイアスを定義します。
- Parabolic SAR のステップ 0.02、最大値 0.2 は、価格がすでにトレンドの新しい側にブレイクしていることを確認します。
- ロングエントリー
- EMA(10) は、EMA(25) と EMA(50) の両方より大きいです。
- EMA(10) は、前のクローズされたローソク足の EMA(50) を下回っていました (クロスアップ確認)。
- Parabolic SAR の値はローソク足の終値を下回っており、ドットが強気モードに切り替わったことを意味します。
- 未オープンのポジションは存在せず、ストラテジーは取引を許可されています (オンライン + 権限)。
- 短いエントリー
- EMA(10) は、EMA(25) と EMA(50) の両方よりも低いです。
- EMA(10) は、前のクローズされたローソク足の EMA(50) を上回っていました (クロスダウン確認)。
- Parabolic SAR はローソク足の終値を上回っています。
- 出口管理
- ハードストップロスとテイクプロフィットは、ロングトレードとショートトレードの非対称設定でエントリー直後に適用されます。
- 価格がポジションに十分有利に動くと、トレーリングストップが装備されます。停留所は
current price -/+ trailing まで引かれています
方向によっては距離が異なります。
- 早期終了は、EMA(10) の方向が反転し (ロングの場合は前の値を下回るか、ショートの場合は上に上昇する)、
オープン利益が最小トリガー距離を超えています。
デフォルトのパラメータ値
| パラメータ |
デフォルト |
説明 |
CandleType |
15分の時間枠 |
戦略的に加工されたキャンドルシリーズ。 |
FastEmaLength |
10 |
高速の EMA の期間。 |
MediumEmaLength |
25 |
媒体 EMA の期間。 |
SlowEmaLength |
50 |
遅い EMA の期間。 |
SarStep |
0.02 |
Parabolic SAR の初期加速。 |
SarMax |
0.2 |
Parabolic SAR の最大加速度。 |
Volume |
0.1 |
ロット/契約の取引量。 |
LongTakeProfitPoints |
50 |
価格ポイントで測定されたロング取引の利食い距離。 |
ShortTakeProfitPoints |
50 |
価格ポイントで測定されたショートトレードの利食い距離。 |
LongStopLossPoints |
30 |
価格ポイントで測定されるロング取引のストップロス距離。 |
ShortStopLossPoints |
30 |
価格ポイントで測定される短期取引のストップロス距離。 |
LongTrailingStopPoints |
10 |
ロングトレードのトレーリングストップトリガー距離。 |
ShortTrailingStopPoints |
10 |
ショートトレードのトレーリングストップトリガー距離。 |
LongProfitTriggerPoints |
10 |
EMA の反転でロングトレードを終了するために必要な最小オープン利益 (ポイント)。 |
ShortProfitTriggerPoints |
5 |
EMA の反転でショートトレードを閉じるために必要な最小オープン利益 (ポイント)。 |
実装メモ
- この戦略では、すべてのリスク管理を内部で維持しながら、ハイレベルの API でローソク足のサブスクリプションとインジケーター バインディングを使用します。
戦略クラス。低レベルのオーダーブックへのアクセスは必要ありません。
- すべての取引管理距離は、商品
PriceStep を使用してポイントから実際の価格オフセットに変換されます。 PriceStepの場合
は利用できませんが、生のポイント値が使用されるため、アルゴリズムは合成楽器でも機能します。
- プロテクティブストップ (
SetStopLoss、SetTakeProfit) は、成行注文が送信されて維持された後のポジションを使用して設定されます。
潜在的な部分フィルと同期します。
- 内部状態は方向ごとの最後のエントリー価格を追跡するため、後続および EMA ベースの出口は実現された価格を評価できます。
正確に進みます。
- すべてのロジックは完成したキャンドルで実行されるため、再描画のリスクはなく、信号は元の MetaTrader の動作を反映します。
start() の終値に基づいてすべてを計算しました。
推奨される使用方法
- この方法は、日中チャート (デフォルトは 15 分) の流動的な FX ペアに適しています。を調整することで、より長い時間枠を使用できます。
EMA 期間とそれに応じた取引管理距離。
- ティックサイズやボラティリティレベルが異なる資産の場合は、ポイントベースのパラメータ(
StopLoss、TakeProfit、
TrailingStop、ProfitTrigger)、距離が機器プロファイルと一致するようにします。
- 会場が特定の時間帯に広範囲に広がる場合は、スプレッド フィルターまたはセッション フィルターと組み合わせます。戦略は合理的であることを期待している
短期的な勢いの爆発を実現するための実行。
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class ForexProfitSystemStrategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast; private decimal _prevSlow; private bool _hasPrev;
private int _cooldown;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public ForexProfitSystemStrategy()
{
_fastPeriod = Param(nameof(FastPeriod), 10).SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 25).SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevFast = default;
_prevSlow = default;
_hasPrev = default;
_cooldown = default;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) return;
if (!_hasPrev) { _prevFast = fast; _prevSlow = slow; _hasPrev = true; return; }
if (_cooldown > 0)
{
_cooldown--;
_prevFast = fast; _prevSlow = slow;
return;
}
if (_prevFast <= _prevSlow && fast > slow && Position <= 0)
{
var volume = Volume + Math.Abs(Position);
BuyMarket(volume);
_cooldown = 2;
}
else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)
{
var volume = Volume + Math.Abs(Position);
SellMarket(volume);
_cooldown = 2;
}
_prevFast = fast; _prevSlow = slow;
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class forex_profit_system_strategy(Strategy):
def __init__(self):
super(forex_profit_system_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 10).SetDisplay("Fast EMA", "Fast EMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 25).SetDisplay("Slow EMA", "Slow EMA period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(15))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_fast = 0.0; self._prev_slow = 0.0; self._has_prev = False; self._cooldown = 0
@property
def fast_period(self): return self._fast_period.Value
@property
def slow_period(self): return self._slow_period.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(forex_profit_system_strategy, self).OnReseted()
self._prev_fast = 0.0; self._prev_slow = 0.0; self._has_prev = False; self._cooldown = 0
def OnStarted2(self, time):
super(forex_profit_system_strategy, self).OnStarted2(time)
self._has_prev = False; self._cooldown = 0
fast = ExponentialMovingAverage(); fast.Length = self.fast_period
slow = ExponentialMovingAverage(); slow.Length = self.slow_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast, slow, self.process_candle).Start()
def process_candle(self, candle, fast, slow):
if candle.State != CandleStates.Finished: return
if not self.IsFormedAndOnlineAndAllowTrading(): return
fast_val = float(fast); slow_val = float(slow)
if not self._has_prev:
self._prev_fast = fast_val; self._prev_slow = slow_val; self._has_prev = True; return
if self._cooldown > 0:
self._cooldown -= 1; self._prev_fast = fast_val; self._prev_slow = slow_val; return
if self._prev_fast <= self._prev_slow and fast_val > slow_val and self.Position <= 0:
volume = self.Volume + abs(self.Position)
self.BuyMarket(volume); self._cooldown = 2
elif self._prev_fast >= self._prev_slow and fast_val < slow_val and self.Position >= 0:
volume = self.Volume + abs(self.Position)
self.SellMarket(volume); self._cooldown = 2
self._prev_fast = fast_val; self._prev_slow = slow_val
def CreateClone(self): return forex_profit_system_strategy()