EMA 10/20/50 アライメント戦略
このロングのみの戦略は、EMA(10) > EMA(20) > EMA(50) のときにエントリーし、EMAが降順に並んだときにエグジットします。取引は設定可能な日付範囲に制限されます。
詳細
- エントリー条件: 指定された日付範囲内でEMA(10)がEMA(20)を上回り、EMA(20)がEMA(50)を上回る。
- ロング/ショート: ロングのみ。
- エグジット条件: EMAが下向きに並ぶ (EMA(10) < EMA(20) < EMA(50))。
- ストップ: なし。
- デフォルト値:
StartTime= new DateTimeOffset(2023, 5, 17, 0, 0, 0, TimeSpan.Zero)EndTime= new DateTimeOffset(2025, 5, 17, 0, 0, 0, TimeSpan.Zero)CandleType= TimeSpan.FromMinutes(1)
- フィルター:
- カテゴリ: トレンド
- 方向: ロング
- インジケーター: 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>
/// EMA 10/20/50 alignment strategy.
/// Long only: buys when EMA(10) is above EMA(20) and EMA(20) is above EMA(50) and closes the long when the three EMAs align
/// in descending order. Entries are allowed only for candles between StartTime and EndTime.
/// </summary>
public class Ema102050AlignmentStrategy : Strategy
{
private readonly StrategyParam<DateTimeOffset> _startTime;
private readonly StrategyParam<DateTimeOffset> _endTime;
private readonly StrategyParam<DataType> _candleType;
/// <summary>
/// Start of the trading date range.
/// </summary>
public DateTimeOffset StartTime
{
get => _startTime.Value;
set => _startTime.Value = value;
}
/// <summary>
/// End of the trading date range.
/// </summary>
public DateTimeOffset EndTime
{
get => _endTime.Value;
set => _endTime.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public Ema102050AlignmentStrategy()
{
_startTime = Param(nameof(StartTime), new DateTimeOffset(2023, 5, 17, 0, 0, 0, TimeSpan.Zero))
.SetDisplay("Start Time", "Start of the trading date range", "General");
_endTime = Param(nameof(EndTime), new DateTimeOffset(2025, 5, 17, 0, 0, 0, TimeSpan.Zero))
.SetDisplay("End Time", "End of the trading date range", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema10 = new ExponentialMovingAverage { Length = 10 };
var ema20 = new ExponentialMovingAverage { Length = 20 };
var ema50 = new ExponentialMovingAverage { Length = 50 };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema10, ema20, ema50, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema10);
DrawIndicator(area, ema20);
DrawIndicator(area, ema50);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal ema10, decimal ema20, decimal ema50)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var inRange = candle.OpenTime >= StartTime.UtcDateTime && candle.OpenTime <= EndTime.UtcDateTime;
if (Position <= 0 && inRange && ema10 > ema20 && ema20 > ema50)
BuyMarket(Volume + Math.Abs(Position));
else if (Position > 0 && ema10 < ema20 && ema20 < ema50)
SellMarket(Position);
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, DateTimeOffset
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class ema_10_20_50_alignment_strategy(Strategy):
"""
EMA 10/20/50 alignment strategy.
Long only: buys when EMA(10) is above EMA(20) and EMA(20) is above EMA(50) and closes the long when the three EMAs align
in descending order. Entries are allowed only for candles between StartTime and EndTime.
"""
def __init__(self):
super(ema_10_20_50_alignment_strategy, self).__init__()
self._start_time = self.Param("StartTime", DateTimeOffset(2023, 5, 17, 0, 0, 0, TimeSpan.Zero)).SetDisplay("Start Time", "Start of the trading date range", "General")
self._end_time = self.Param("EndTime", DateTimeOffset(2025, 5, 17, 0, 0, 0, TimeSpan.Zero)).SetDisplay("End Time", "End of the trading date range", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(1))).SetDisplay("Candle Type", "Type of candles to use", "General")
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(ema_10_20_50_alignment_strategy, self).OnStarted2(time)
ema10 = ExponentialMovingAverage()
ema10.Length = 10
ema20 = ExponentialMovingAverage()
ema20.Length = 20
ema50 = ExponentialMovingAverage()
ema50.Length = 50
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ema10, ema20, ema50, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema10)
self.DrawIndicator(area, ema20)
self.DrawIndicator(area, ema50)
self.DrawOwnTrades(area)
def _process_candle(self, candle, ema10_value, ema20_value, ema50_value):
if candle.State != CandleStates.Finished:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
ema10 = float(ema10_value)
ema20 = float(ema20_value)
ema50 = float(ema50_value)
open_ticks = candle.OpenTime.Ticks
in_range = self._start_time.Value.UtcDateTime.Ticks <= open_ticks <= self._end_time.Value.UtcDateTime.Ticks
if self.Position <= 0 and in_range and ema10 > ema20 and ema20 > ema50:
self.BuyMarket(self.Volume + abs(self.Position))
elif self.Position > 0 and ema10 < ema20 and ema20 < ema50:
self.SellMarket(self.Position)
def CreateClone(self):
return ema_10_20_50_alignment_strategy()