ライブAlligator戦略
この戦略は動的なAlligator設定といくつかのEMAフィルターを使用してトレンドの反転を取引します。
AlligatorラインがL方向を変えて5つのEMAが動きを確認するときに新しいポジションを建てます。
オプションの取引時間フィルターにより選択したセッションへのエントリーを制限します。
価格がTrailPeriodに基づくトレーリング平滑移動平均線をクロスするとオープンポジションをクローズします。
- エントリー条件
- AlligatorのLipsがJawsの上にあり、TeethがJawsの下にあり、前のバーのLipsがJawsの下にある -> 弱気トレンド後にロングを建てる。
- AlligatorのLipsがJawsの下にあり、TeethがJawsの上にあり、前のバーのLipsがJawsの上にある -> 強気トレンド後にショートを建てる。
- 終値、加重値、典型値、中央値、始値に対する5つのEMAがトレンドの方向に厳密に並んでいる必要がある。
- エグジット条件
- 価格が
TrailPeriodに基づくトレーリングSMMAをクロス。 - 取引開始時にオプションのストップロスを適用。
- 価格が
- 使用するインジケーター
- AlligatorラインとトレーリングストップのSMMA。
- 異なる価格タイプでのEMA。
パラメーターでAlligatorのベース期間、EMA確認期間、トレーリング期間、ストップロス、取引時間ウィンドウを設定できます。
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Alligator strategy using three smoothed moving averages (jaw, teeth, lips).
/// Buys when lips cross above jaw; sells when lips cross below jaw.
/// Uses a trailing SMA for exit.
/// </summary>
public class LiveAlligatorStrategy : Strategy
{
private readonly StrategyParam<int> _jawLength;
private readonly StrategyParam<int> _teethLength;
private readonly StrategyParam<int> _lipsLength;
private readonly StrategyParam<int> _trailLength;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevLips;
private decimal _prevJaw;
private decimal _prevTrail;
private bool _hasPrev;
public int JawLength { get => _jawLength.Value; set => _jawLength.Value = value; }
public int TeethLength { get => _teethLength.Value; set => _teethLength.Value = value; }
public int LipsLength { get => _lipsLength.Value; set => _lipsLength.Value = value; }
public int TrailLength { get => _trailLength.Value; set => _trailLength.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public LiveAlligatorStrategy()
{
_jawLength = Param(nameof(JawLength), 21)
.SetGreaterThanZero()
.SetDisplay("Jaw", "Alligator Jaw length", "Indicators");
_teethLength = Param(nameof(TeethLength), 13)
.SetGreaterThanZero()
.SetDisplay("Teeth", "Alligator Teeth length", "Indicators");
_lipsLength = Param(nameof(LipsLength), 8)
.SetGreaterThanZero()
.SetDisplay("Lips", "Alligator Lips length", "Indicators");
_trailLength = Param(nameof(TrailLength), 50)
.SetGreaterThanZero()
.SetDisplay("Trail", "Trailing SMA length", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevLips = 0;
_prevJaw = 0;
_prevTrail = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var jaw = new SmoothedMovingAverage { Length = JawLength };
var teeth = new SmoothedMovingAverage { Length = TeethLength };
var lips = new SmoothedMovingAverage { Length = LipsLength };
var trail = new SimpleMovingAverage { Length = TrailLength };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(jaw, teeth, lips, trail, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal jawVal, decimal teethVal, decimal lipsVal, decimal trailVal)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevLips = lipsVal;
_prevJaw = jawVal;
_prevTrail = trailVal;
_hasPrev = true;
return;
}
var close = candle.ClosePrice;
// Lips cross above jaw -> uptrend start
if (_prevLips <= _prevJaw && lipsVal > jawVal && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Lips cross below jaw -> downtrend start
else if (_prevLips >= _prevJaw && lipsVal < jawVal && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
// Trail exit: close below trail for longs
if (Position > 0 && close < _prevTrail)
{
SellMarket();
}
// Trail exit: close above trail for shorts
else if (Position < 0 && close > _prevTrail)
{
BuyMarket();
}
_prevLips = lipsVal;
_prevJaw = jawVal;
_prevTrail = trailVal;
}
}
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, SmoothedMovingAverage
from StockSharp.Algo.Strategies import Strategy
class live_alligator_strategy(Strategy):
def __init__(self):
super(live_alligator_strategy, self).__init__()
self._jaw_length = self.Param("JawLength", 21) \
.SetDisplay("Jaw", "Alligator Jaw length", "Indicators")
self._teeth_length = self.Param("TeethLength", 13) \
.SetDisplay("Teeth", "Alligator Teeth length", "Indicators")
self._lips_length = self.Param("LipsLength", 8) \
.SetDisplay("Lips", "Alligator Lips length", "Indicators")
self._trail_length = self.Param("TrailLength", 50) \
.SetDisplay("Trail", "Trailing SMA length", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._prev_lips = 0.0
self._prev_jaw = 0.0
self._prev_trail = 0.0
self._has_prev = False
@property
def jaw_length(self):
return self._jaw_length.Value
@property
def teeth_length(self):
return self._teeth_length.Value
@property
def lips_length(self):
return self._lips_length.Value
@property
def trail_length(self):
return self._trail_length.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(live_alligator_strategy, self).OnReseted()
self._prev_lips = 0.0
self._prev_jaw = 0.0
self._prev_trail = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(live_alligator_strategy, self).OnStarted2(time)
jaw = SmoothedMovingAverage()
jaw.Length = self.jaw_length
teeth = SmoothedMovingAverage()
teeth.Length = self.teeth_length
lips = SmoothedMovingAverage()
lips.Length = self.lips_length
trail = SimpleMovingAverage()
trail.Length = self.trail_length
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(jaw, teeth, lips, trail, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def on_process(self, candle, jaw_val, teeth_val, lips_val, trail_val):
if candle.State != CandleStates.Finished:
return
if not self._has_prev:
self._prev_lips = lips_val
self._prev_jaw = jaw_val
self._prev_trail = trail_val
self._has_prev = True
return
close = candle.ClosePrice
# Lips cross above jaw -> uptrend start
if self._prev_lips <= self._prev_jaw and lips_val > jaw_val and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
# Lips cross below jaw -> downtrend start
elif self._prev_lips >= self._prev_jaw and lips_val < jaw_val and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
# Trail exit: close below trail for longs
if self.Position > 0 and close < self._prev_trail:
self.SellMarket()
# Trail exit: close above trail for shorts
elif self.Position < 0 and close > self._prev_trail:
self.BuyMarket()
self._prev_lips = lips_val
self._prev_jaw = jaw_val
self._prev_trail = trail_val
def CreateClone(self):
return live_alligator_strategy()