GitHub で見る
ADX & MA 戦略
概要
この戦略は、MetaTrader エキスパート ADX_MA (フォートレーダー) の StockSharp 移植です。
平滑移動平均 (SMMA) フィルターと平均方向インデックス (ADX) を組み合わせます。
トレンドがクロスオーバーによって確認され、十分に強い場合にのみ取引が行われるようにする
ADXによると。ポートは、元のロボットからの非対称リスク管理を維持します。
ロングポジションでは広いテイクプロフィットとトレーリングディスタンスを使用し、ショートトレードではよりタイトな距離を使用します。
ターゲットと保護。
取引ロジック
- ローソク足の中央値と設定された期間で ADX の平滑移動平均を作成します。
- MQL4 ロジック (
iClose(...,1) / iClose(...,2)) を模倣する目的でのみ、閉じたローソク足のシグナルを評価します。
- 前のローソク足が SMMA を上回って終了したときにロングに入り、その前のローソク足が SMMA を下回って終了したときにエントリーします。
SMMA 値が同じで、前の ADX の読み取り値がしきい値を超えています。
- 前のローソク足が SMMA を下回って終了したとき、ショートに入る。その前のローソク足が SMMA を上回って終了したとき。
SMMA 値が同じで、ADX がしきい値を超えています。
- 所定の位置に配置されると、出口は以下によって駆動されます。
- 移動平均を逆方向に反転します。
- ピップ単位で測定される個々のストップロスとテイクプロフィットのレベル。
- 取引に有利なオプションのトレーリングストップ距離。
すべての価格オフセットは、証券の価格ステップを使用してピップから変換されます。機器がそうでない場合は、
有効なステップをレポートする場合、値 1 が安全なフォールバックとして使用されます。
パラメーター
| 名前 |
説明 |
SMMA Period |
平滑化移動平均の長さ (デフォルトは 21)。 |
ADX Period |
平均方向インデックスの長さ (デフォルトは 14)。 |
ADX Threshold |
エントリを許可するには最小の ADX 値が必要です (デフォルトは 16)。 |
Long Take Profit (pips) |
買いポジションの利食い距離 (デフォルトは 1300 ピップス)。 |
Long Stop Loss (pips) |
買いポジションのストップロス距離 (デフォルトは 30 ピップス)。 |
Long Trailing Stop (pips) |
買いポジションのトレーリングストップ距離 (デフォルトは 270 ピップス)。 |
Short Take Profit (pips) |
売りポジションの利食い距離 (デフォルトは 160 ピップス)。 |
Short Stop Loss (pips) |
売りポジションのストップロス距離 (デフォルトは 50 ピップス)。 |
Short Trailing Stop (pips) |
売りポジションのトレーリングストップ距離 (デフォルトは 20 ピップス)。 |
Volume |
新規エントリーに使用される注文量 (デフォルトは 0.1)。 |
Candle Type |
計算用の主要なローソク足シリーズ (デフォルトの 1 分の時間枠)。 |
すべてのパラメータは最適化のために公開されます。デフォルトは元の EA 設定と一致します。
注意事項
- トレーリングストップは、価格がエントリーから少なくとも設定された距離だけ移動した後にのみ有効になります。
- 反対のシグナルは、新しいポジションを開く前にアクティブなポジションを閉じます。
- チャート領域が利用可能な場合、ストラテジーはチャート上にローソク足、インジケーター、および独自の取引を自動的に描画します。
- このポートには自動テストはありません。手動バックテストを使用して、機器の動作を検証します。
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class AdxMaStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<int> _smaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevClose; private decimal _prevEma; private bool _hasPrev;
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public int SmaPeriod { get => _smaPeriod.Value; set => _smaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public AdxMaStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 14).SetDisplay("EMA Period", "EMA lookback", "Indicators");
_smaPeriod = Param(nameof(SmaPeriod), 50).SetDisplay("SMA Period", "SMA trend filter", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
protected override void OnReseted()
{
base.OnReseted();
_prevClose = 0;
_prevEma = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal ema)
{
if (candle.State != CandleStates.Finished) return;
var close = candle.ClosePrice;
if (!_hasPrev) { _prevClose = close; _prevEma = ema; _hasPrev = true; return; }
if (_prevClose <= _prevEma && close > ema && Position <= 0)
{ if (Position < 0) BuyMarket(); BuyMarket(); }
else if (_prevClose >= _prevEma && close < ema && Position >= 0)
{ if (Position > 0) SellMarket(); SellMarket(); }
_prevClose = close; _prevEma = ema;
}
}
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 CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
class adx_ma_strategy(Strategy):
"""
ADX MA strategy: EMA crossover with price for trend-following entries.
"""
def __init__(self):
super(adx_ma_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 14) \
.SetDisplay("EMA Period", "EMA lookback", "Indicators")
self._sma_period = self.Param("SmaPeriod", 50) \
.SetDisplay("SMA Period", "SMA trend filter", "Indicators")
self._candle_type = self.Param("CandleType", tf(5)) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_close = 0.0
self._prev_ema = 0.0
self._has_prev = False
@property
def EmaPeriod(self):
return self._ema_period.Value
@EmaPeriod.setter
def EmaPeriod(self, value):
self._ema_period.Value = value
@property
def SmaPeriod(self):
return self._sma_period.Value
@SmaPeriod.setter
def SmaPeriod(self, value):
self._sma_period.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnReseted(self):
super(adx_ma_strategy, self).OnReseted()
self._prev_close = 0.0
self._prev_ema = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(adx_ma_strategy, self).OnStarted2(time)
self._has_prev = False
ema = ExponentialMovingAverage()
ema.Length = self.EmaPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, self.ProcessCandle).Start()
def ProcessCandle(self, candle, ema):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
if not self._has_prev:
self._prev_close = close
self._prev_ema = ema
self._has_prev = True
return
if self._prev_close <= self._prev_ema and close > ema and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._prev_close >= self._prev_ema and close < ema and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_close = close
self._prev_ema = ema
def CreateClone(self):
"""!! REQUIRED!! Creates a new instance of the strategy."""
return adx_ma_strategy()