GitHub で見る
AMA トレーダー v2.1 戦略
AMA Trader v2.1 ストラテジーは、MetaTrader 4 エキスパート アドバイザー AMA_TRADER_v2_1.mq4 の変換であり、カウフマンの適応移動平均 (AMA) バーストと二重平滑化平均足フィルターおよび RSI のモメンタム チェックを組み合わせたものです。
中核ロジック
- 適応トレンド フィルター – カスタム AMA エンジンは、高速/低速定数、効率比、パワー パラメーターなどの元のインジケーターを再現します。アルゴリズムは、AMA 値が前の足と比較して
AmaThreshold 価格ステップを超えて跳ね上がる勢いのバーストを監視します。
- 平均足の確認 – 価格ローソク足は 2 回平滑化されます。最初は生の OHLC 価格の設定可能な移動平均によって、次に平均足バッファーの 2 番目の移動平均によって平滑化されます。強気(終値が始値を上回る)で平滑化されたバーではロング取引が可能ですが、弱気のバーではショートが可能です。
- RSI モメンタム チェック – 設定可能な期間を備えた古典的な RSI でモメンタムを確認します。ロングの場合は、RSI が 70 未満に留まりながら前の値から引き戻す必要があり、ショートの場合はオシレーターが 30 を超えている間にバウンスする必要があります。
- ポジション管理 – この戦略は、一度に 1 つのポジションをオープンし、オプションのストップロスとテイクプロフィットの距離 (価格ステップ単位) を適用し、価格が取引方向に移動するとストップを追跡することができます。 RSI が 70/30 の極値を超えると、次の交差点で完全に終了する前に、オプションの部分的なクローズが実行されます。
パラメーター
| 名前 |
デフォルト |
説明 |
CandleType |
15分キャンドル |
すべての計算の時間枠。 |
TradeVolume |
0.1 |
基本市場注文量。 |
AmaLength |
9 |
適応移動平均によって使用されるルックバック。 |
AmaFastPeriod |
2 |
AMA スムージングのためのバー単位の高速定数。 |
AmaSlowPeriod |
30 |
AMA スムージングのためのバー単位の遅い定数。 |
AmaPower |
2 |
平滑化定数に適用される指数 (MQ4 コードの G と一致します)。 |
AmaThreshold |
2ステップ |
シグナルをトリガーするための最小 AMA 変更 (価格ステップ単位)。 |
FirstMaMethod |
滑らかにした |
平均足構築の最初のスムージング手法。 |
FirstMaPeriod |
6 |
最初の平滑移動平均の長さ。 |
SecondMaMethod |
線形加重 |
平均足バッファーに適用される 2 番目の平滑化方法。 |
SecondMaPeriod |
2 |
2 番目の平滑移動平均の長さ。 |
RsiPeriod |
14 |
運動量フィルターで使用される RSI 期間。 |
PartialClosePercent |
70% |
RSI が極値を超えたときに閉じるアクティブ ポジションの部分。無効にするには、0 に設定します。 |
StopLossSteps |
50 |
商品の価格ステップで表されるストップロス距離。無効にするには、0 に設定します。 |
TakeProfitSteps |
100 |
価格ステップで表される利食い距離。無効にするには、0 に設定します。 |
TrailingSteps |
30 |
価格ステップでのトレーリングストップ距離。末尾を無効にするには、0 に設定します。 |
取引ルール
- ロングエントリー – AMA ジャンプがプラスで
AmaThreshold を超えると、最新の平滑化平均足ローソク足は強気となり、RSI は 70 以下に留まりながら(以前の値が現在の値より大きい)引き戻されます。
- ショートエントリー – AMA ジャンプが
AmaThreshold を超えてマイナスになっている場合、平滑化された平均足ローソク足は弱気で、RSI は 30 以上に留まりながら上昇しています (以前の値が現在よりも小さい)。
- 部分決済 – 有効にすると、RSI が 70 を超える (ロング) または 30 を下回る (ショート) ときにポジションの
PartialClosePercent を決済します。
- フルイグジット – 反対側の RSI の極値、ストップロス、テイクプロフィット、またはトレーリングストップに達したときにポジション全体をクローズします。
この実装では、高レベルの StockSharp API を使用します。キャンドル サブスクリプションは、カスタム AMA 計算機、平均足平滑化パイプライン、および RSI インジケーターにフィードします。ソース コード内のすべてのコメントは英語であり、変換ガイドラインの要件を反映しています。
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class AmaTraderV21Strategy : 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 AmaTraderV21Strategy()
{
_fastPeriod = Param(nameof(FastPeriod), 10).SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 30).SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
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 (!_hasPrev) { _prevFast = fast; _prevSlow = slow; _hasPrev = true; return; }
if (_cooldown > 0) { _cooldown--; _prevFast = fast; _prevSlow = slow; return; }
if (_prevFast <= _prevSlow && fast > slow && Position <= 0)
{ if (Position < 0) BuyMarket(); BuyMarket(); _cooldown = 140; }
else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)
{ if (Position > 0) SellMarket(); SellMarket(); _cooldown = 140; }
_prevFast = fast; _prevSlow = slow;
}
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
_cooldown = 0;
}
}
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 ama_trader_v21_strategy(Strategy):
"""
AMA Trader V2.1: dual EMA crossover strategy.
"""
def __init__(self):
super(ama_trader_v21_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 10) \
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 30) \
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators")
self._candle_type = self.Param("CandleType", tf(5)) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
@property
def FastPeriod(self): return self._fast_period.Value
@FastPeriod.setter
def FastPeriod(self, v): self._fast_period.Value = v
@property
def SlowPeriod(self): return self._slow_period.Value
@SlowPeriod.setter
def SlowPeriod(self, v): self._slow_period.Value = v
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, v): self._candle_type.Value = v
def OnReseted(self):
super(ama_trader_v21_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(ama_trader_v21_strategy, self).OnStarted2(time)
self._has_prev = False
fast = ExponentialMovingAverage()
fast.Length = self.FastPeriod
slow = ExponentialMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast, slow, self.ProcessCandle).Start()
def ProcessCandle(self, candle, fast, slow):
if candle.State != CandleStates.Finished:
return
if not self._has_prev:
self._prev_fast = fast
self._prev_slow = slow
self._has_prev = True
return
if self._prev_fast <= self._prev_slow and fast > slow and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._prev_fast >= self._prev_slow and fast < slow and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_fast = fast
self._prev_slow = slow
def CreateClone(self):
"""!! REQUIRED!! Creates a new instance of the strategy."""
return ama_trader_v21_strategy()