GitHub で見る
エキスパート Alligator 戦略
エキスパート Alligator 戦略は、MetaTrader 5 の組み込みエキスパート アドバイザー Expert_Alligator.mq5 の忠実な StockSharp 移植です。元の専門家は、ビル Williams の Alligator インジケーターに基づいて取引の決定を下します。このインジケーターは、顎 (青)、歯 (赤)、唇 (緑) という、将来にシフトされた 3 つの平滑化移動平均で構成されます。これらのラインがどのように収縮および拡大するかを監視することで、EA は新たなクロスオーバーを特定し、別の取引が行われる前に「口」が開くのを待ちます。この C# 変換は、StockSharp の高レベル戦略 API とインジケーター スイートを使用して同じワークフローを再作成します。
取引ロジック
インジケーターの準備
- 従来の Alligator 長さ (13、8、および 5) を使用して中央価格の 3 つの平滑化移動平均を作成し、標準の前方シフト (それぞれ 8、5、および 3 バー) を適用します。
- MetaTrader EA (例:
LipsTeethDiff(-2)) で使用される過去および将来のオフセットを安全に評価できるように、シフトされた各行のローリング履歴を保存します。
エントリー条件
- ロングトレード: 唇と歯および歯と顎のスプレッドが、ゼロを超えたまま、シフトされた 3 つの連続したバーにわたって縮小しているときにトリガーされます。これは、緑の線が赤を通って下に交差するという EA の要件を再現し、上向きの口の開きを確認します。
- ショートトレード: スプレッドがゼロ以下に縮小しているロングロジックを反映しており、唇が歯と顎を通って上向きに交差していることを示しています。
- 取引が開始されると、ストラテジーは内部の
crossed フラグを立てて、3 つの Alligator スプレッドが少なくとも設定された クロス メジャー 距離だけ広がるまで、追加のエントリーをブロックします。
終了条件
- ロングポジションは、唇と歯のスプレッドが、2 つの古い値 (元の EA の
-1、0、1 インデックス) ではプラスのままで、シフトされた最新の値ではマイナスに反転すると閉じられます。
- ショートポジションは、同じシーケンスが反対方向に発生したときに終了します。
パラメーター
| 名前 |
説明 |
デフォルト |
Order Volume |
BuyMarket/SellMarket に渡されるロットまたは契約の取引サイズ。 |
0.1 |
Candle Type |
キャンドルのサブスクリプションの期間。 |
1 Hour |
Jaw Period |
顎のラインの平滑化された移動平均の長さ。 |
13 |
Jaw Shift |
顎のラインの前方変位 (バー単位)。 |
8 |
Teeth Period |
歯のラインの平滑化移動平均長。 |
8 |
Teeth Shift |
歯列の前方変位 (バー単位)。 |
5 |
Lips Period |
唇のラインの平滑化移動平均の長さ。 |
5 |
Lips Shift |
唇のラインの前方変位 (バー単位)。 |
3 |
Cross Measure |
クロスオーバー後に別の取引が開始される前に展開する必要がある最小スプレッド (MetaTrader ポイント)。 |
5 |
実装メモ
- この戦略は、完成した各ローソクの中央価格
(High + Low) / 2 を計算し、それを 3 つの SmoothedMovingAverage インスタンスにフィードします。
- シフトされた履歴は、Alligator 行が前方に移動された後に、MetaTrader が
-1 や -2 のような将来のインデックスを公開する方法をミラーリングするために、固定サイズの配列で実装されます。
- MetaTrader
_Point 値は、シンボルの PriceStep を通じてエミュレートされます。後者が利用できない場合、コードは 10^-Decimals または 0.0001 に戻ります。
- チャートの出力は、主ローソク足パネルに顎、歯、唇をプロットすることで EA と一致し、迅速な視覚的検証が可能になります。
使用法
- 希望のローソク足タイプ (デフォルトの 1 時間足ローソク足) を提供する証券を使用して、ストラテジーを
Connector にアタッチします。
- 市場データ ストリームの準備ができたら、
Start() を呼び出します。
- オプション: Alligator の長さ、シフト、またはクロスメジャーしきい値を調整して、カスタム動作をテストします。
- 標準の StockSharp インターフェースを通じて位置とパフォーマンスを監視します。
元の EA は固定ロット サイズ設定を使用し、取引管理には Alligator ライン ジオメトリのみに依存しているため、追加のトレーリング ストップや資金管理モジュールは必要ありません。
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Expert Alligator strategy: Triple SMA (Alligator concept).
/// Buys when lips > teeth > jaw (bullish alignment).
/// Sells when lips < teeth < jaw (bearish alignment).
/// </summary>
public class ExpertAlligatorStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public ExpertAlligatorStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
// Alligator: Jaw=13, Teeth=8, Lips=5
var lips = new SimpleMovingAverage { Length = 5 };
var teeth = new SimpleMovingAverage { Length = 8 };
var jaw = new SimpleMovingAverage { Length = 13 };
decimal? prevLips = null;
decimal? prevTeeth = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(lips, teeth, jaw, (candle, lipsVal, teethVal, jawVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (prevLips.HasValue && prevTeeth.HasValue)
{
var lipsCrossUp = prevLips.Value <= prevTeeth.Value && lipsVal > teethVal;
var lipsCrossDown = prevLips.Value >= prevTeeth.Value && lipsVal < teethVal;
if (lipsCrossUp && teethVal > jawVal && Position <= 0)
BuyMarket();
else if (lipsCrossDown && teethVal < jawVal && Position >= 0)
SellMarket();
}
prevLips = lipsVal;
prevTeeth = teethVal;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, lips);
DrawIndicator(area, teeth);
DrawIndicator(area, jaw);
DrawOwnTrades(area);
}
}
}
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 expert_alligator_strategy(Strategy):
def __init__(self):
super(expert_alligator_strategy, self).__init__()
self._lips = None
self._teeth = None
self._jaw = None
self._prev_lips = None
self._prev_teeth = None
def OnReseted(self):
super(expert_alligator_strategy, self).OnReseted()
self._lips = None
self._teeth = None
self._jaw = None
self._prev_lips = None
self._prev_teeth = None
def OnStarted2(self, time):
super(expert_alligator_strategy, self).OnStarted2(time)
self._lips = SimpleMovingAverage()
self._lips.Length = 5
self._teeth = SimpleMovingAverage()
self._teeth.Length = 8
self._jaw = SimpleMovingAverage()
self._jaw.Length = 13
subscription = self.SubscribeCandles(DataType.TimeFrame(TimeSpan.FromMinutes(30)))
subscription.Bind(self._lips, self._teeth, self._jaw, self._process_candle)
subscription.Start()
def _process_candle(self, candle, lips_value, teeth_value, jaw_value):
if candle.State != CandleStates.Finished:
return
if not self._lips.IsFormed or not self._teeth.IsFormed or not self._jaw.IsFormed:
return
lips_val = float(lips_value)
teeth_val = float(teeth_value)
jaw_val = float(jaw_value)
if self._prev_lips is not None and self._prev_teeth is not None:
lips_cross_up = self._prev_lips <= self._prev_teeth and lips_val > teeth_val
lips_cross_down = self._prev_lips >= self._prev_teeth and lips_val < teeth_val
if lips_cross_up and teeth_val > jaw_val and self.Position <= 0:
self.BuyMarket()
elif lips_cross_down and teeth_val < jaw_val and self.Position >= 0:
self.SellMarket()
self._prev_lips = lips_val
self._prev_teeth = teeth_val
def CreateClone(self):
return expert_alligator_strategy()