EMA 34 クロスオーバーとブレークイーブン・ストップロス戦略
EMA 34 Crossover with Break Even Stop Loss 戦略は、価格が34期間EMAを上抜けしたときにロングポジションを取ります。ストップロスは前のローソク足の安値に置き、テイクプロフィットはリスクの10倍、価格がリスクの3倍に達した後はストップをブレークイーブンに移動させます。
詳細
- エントリー条件: 終値が EMA(34) を下から上にクロスする。
- ロング/ショート: ロングのみ。
- エグジット条件: 前の安値でのストップロスまたは10×リスクでのテイクプロフィット。
- ストップ: はい、ブレークイーブン・ストップ。
- デフォルト値:
EmaPeriod = 34TakeProfitMultiplier = 10mBreakEvenMultiplier = 3mCandleType = TimeSpan.FromMinutes(5).TimeFrame()
- フィルター:
- カテゴリ: トレンドフォロー
- 方向: ロング
- インジケーター: EMA
- ストップ: はい
- 複雑さ: 初心者
- 時間軸: イントラデイ (5m)
- 季節性: いいえ
- ニューラルネットワーク: いいえ
- ダイバージェンス: いいえ
- リスクレベル: 中
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 34 crossover with break even stop loss strategy.
/// Long only: buys when the close crosses above the EMA from below. The stop is the previous candle's low, the take profit lies
/// TakeProfitMultiplier times the risk above the entry, and the stop moves to the entry price once price has gone
/// BreakEvenMultiplier times the risk in favour.
/// </summary>
public class Ema34CrossoverWithBreakEvenStopLossStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<decimal> _takeProfitMultiplier;
private readonly StrategyParam<decimal> _breakEvenMultiplier;
private readonly StrategyParam<DataType> _candleType;
private decimal? _prevClose;
private decimal? _prevEma;
private decimal? _prevLow;
private decimal _entryPrice;
private decimal _stopPrice;
private decimal _takePrice;
private decimal _breakEvenPrice;
/// <summary>
/// EMA period.
/// </summary>
public int EmaPeriod
{
get => _emaPeriod.Value;
set => _emaPeriod.Value = value;
}
/// <summary>
/// Take profit distance in multiples of the risk.
/// </summary>
public decimal TakeProfitMultiplier
{
get => _takeProfitMultiplier.Value;
set => _takeProfitMultiplier.Value = value;
}
/// <summary>
/// Favourable move in multiples of the risk that moves the stop to break even.
/// </summary>
public decimal BreakEvenMultiplier
{
get => _breakEvenMultiplier.Value;
set => _breakEvenMultiplier.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public Ema34CrossoverWithBreakEvenStopLossStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 34)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA period", "Indicators");
_takeProfitMultiplier = Param(nameof(TakeProfitMultiplier), 10m)
.SetGreaterThanZero()
.SetDisplay("Take Profit Multiplier", "Take profit distance in multiples of the risk", "Risk");
_breakEvenMultiplier = Param(nameof(BreakEvenMultiplier), 3m)
.SetGreaterThanZero()
.SetDisplay("Break Even Multiplier", "Favourable move in multiples of the risk that moves the stop to entry", "Risk");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).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 OnReseted()
{
base.OnReseted();
ResetState();
}
private void ResetState()
{
_prevClose = null;
_prevEma = null;
_prevLow = null;
_entryPrice = 0m;
_stopPrice = 0m;
_takePrice = 0m;
_breakEvenPrice = 0m;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
ResetState();
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ema);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal ema)
{
if (candle.State != CandleStates.Finished)
return;
var prevClose = _prevClose;
var prevEma = _prevEma;
var prevLow = _prevLow;
_prevClose = candle.ClosePrice;
_prevEma = ema;
_prevLow = candle.LowPrice;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (Position > 0)
{
if (candle.LowPrice <= _stopPrice || candle.HighPrice >= _takePrice)
{
SellMarket(Position);
return;
}
if (_stopPrice < _entryPrice && candle.HighPrice >= _breakEvenPrice)
_stopPrice = _entryPrice;
return;
}
if (prevClose is not decimal pc || prevEma is not decimal pe || prevLow is not decimal stop)
return;
var close = candle.ClosePrice;
if (pc <= pe && close > ema)
{
var risk = close - stop;
if (risk <= 0m)
return;
_entryPrice = close;
_stopPrice = stop;
_takePrice = close + risk * TakeProfitMultiplier;
_breakEvenPrice = close + risk * BreakEvenMultiplier;
BuyMarket(Volume);
}
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class ema_34_crossover_with_break_even_stop_loss_strategy(Strategy):
"""
EMA 34 crossover with break even stop loss strategy.
Long only: buys when the close crosses above the EMA from below. The stop is the previous candle's low, the take profit lies
TakeProfitMultiplier times the risk above the entry, and the stop moves to the entry price once price has gone
BreakEvenMultiplier times the risk in favour.
"""
def __init__(self):
super(ema_34_crossover_with_break_even_stop_loss_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 34).SetGreaterThanZero().SetDisplay("EMA Period", "EMA period", "Indicators")
self._take_profit_multiplier = self.Param("TakeProfitMultiplier", 10.0).SetGreaterThanZero().SetDisplay("Take Profit Multiplier", "Take profit distance in multiples of the risk", "Risk")
self._break_even_multiplier = self.Param("BreakEvenMultiplier", 3.0).SetGreaterThanZero().SetDisplay("Break Even Multiplier", "Favourable move in multiples of the risk that moves the stop to entry", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._reset_state()
@property
def candle_type(self):
return self._candle_type.Value
def _reset_state(self):
self._prev_close = None
self._prev_ema = None
self._prev_low = None
self._entry_price = 0.0
self._stop_price = 0.0
self._take_price = 0.0
self._break_even_price = 0.0
def OnReseted(self):
super(ema_34_crossover_with_break_even_stop_loss_strategy, self).OnReseted()
self._reset_state()
def OnStarted2(self, time):
super(ema_34_crossover_with_break_even_stop_loss_strategy, self).OnStarted2(time)
self._reset_state()
ema = ExponentialMovingAverage()
ema.Length = self._ema_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ema, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def _process_candle(self, candle, ema_value):
if candle.State != CandleStates.Finished:
return
ema = float(ema_value)
close = float(candle.ClosePrice)
high = float(candle.HighPrice)
low = float(candle.LowPrice)
prev_close = self._prev_close
prev_ema = self._prev_ema
prev_low = self._prev_low
self._prev_close = close
self._prev_ema = ema
self._prev_low = low
if not self.IsFormedAndOnlineAndAllowTrading():
return
if self.Position > 0:
if low <= self._stop_price or high >= self._take_price:
self.SellMarket(self.Position)
return
if self._stop_price < self._entry_price and high >= self._break_even_price:
self._stop_price = self._entry_price
return
if prev_close is None or prev_ema is None or prev_low is None:
return
if prev_close <= prev_ema and close > ema:
risk = close - prev_low
if risk <= 0:
return
self._entry_price = close
self._stop_price = prev_low
self._take_price = close + risk * float(self._take_profit_multiplier.Value)
self._break_even_price = close + risk * float(self._break_even_multiplier.Value)
self.BuyMarket(self.Volume)
def CreateClone(self):
return ema_34_crossover_with_break_even_stop_loss_strategy()