Стратегия CC Trend 2 Downtrend Short
Стратегия только для коротких позиций. Продаёт, когда предыдущая цена закрытия ниже динамического уровня Фибоначчи и EMA21 ниже EMA55. Выходит при пересечении ценой EMA200 при неотрицательной прибыли или когда предыдущая цена закрытия поднимается выше уровня Фибоначчи 0.236 и нет нового сигнала на вход.
Детали
- Условия входа:
- Short: предыдущая цена закрытия ниже максимума Фибоначчи и EMA21 ниже EMA55
- Направление: Short
- Условия выхода:
- Цена пересекает EMA200 при прибыли
- Предыдущая цена закрытия выше уровня Фибоначчи 0.236 без нового сигнала
- Стопы: Нет
- Значения по умолчанию:
FibLength= 100CandleType= TimeSpan.FromMinutes(5).TimeFrame()
- Фильтры:
- Категория: Тренд
- Направление: Short
- Индикаторы: 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>
/// CC Trend Strategy 2 Downtrend Short.
/// Short only. The Fibonacci range spans the lowest low and the highest high of the last FibLength candles, and its 0.236 level lies
/// 23.6% of the range below the high. A short opens when the previous close is below the Fibonacci high and EMA21 is below EMA55.
/// It closes when the close crosses above EMA200 while the trade is not losing, or when the previous close is above the 0.236 level
/// and there is no new short signal.
/// </summary>
public class CCTrend2DowntrendShortStrategy : Strategy
{
private const int _fastEmaLength = 21;
private const int _slowEmaLength = 55;
private const int _trendEmaLength = 200;
private const decimal _fibLevel = 0.236m;
private readonly StrategyParam<int> _fibLength;
private readonly StrategyParam<DataType> _candleType;
private decimal? _prevClose;
private decimal? _prevTrendEma;
private decimal _entryPrice;
/// <summary>
/// Candles of the Fibonacci range.
/// </summary>
public int FibLength
{
get => _fibLength.Value;
set => _fibLength.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public CCTrend2DowntrendShortStrategy()
{
_fibLength = Param(nameof(FibLength), 100)
.SetGreaterThanZero()
.SetDisplay("Fib Length", "Candles of the Fibonacci range", "Fibonacci");
_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();
_prevClose = null;
_prevTrendEma = null;
_entryPrice = 0m;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevClose = null;
_prevTrendEma = null;
_entryPrice = 0m;
var fastEma = new ExponentialMovingAverage { Length = _fastEmaLength };
var slowEma = new ExponentialMovingAverage { Length = _slowEmaLength };
var trendEma = new ExponentialMovingAverage { Length = _trendEmaLength };
var highest = new Highest { Length = FibLength };
var lowest = new Lowest { Length = FibLength };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(fastEma, slowEma, trendEma, highest, lowest, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fastEma);
DrawIndicator(area, slowEma);
DrawIndicator(area, trendEma);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue fastValue, IIndicatorValue slowValue, IIndicatorValue trendValue, IIndicatorValue highestValue, IIndicatorValue lowestValue)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
var prevClose = _prevClose;
var prevTrendEma = _prevTrendEma;
_prevClose = close;
if (!trendValue.IsFormed)
return;
var trendEma = trendValue.GetValue<decimal>();
_prevTrendEma = trendEma;
if (!fastValue.IsFormed || !slowValue.IsFormed || !highestValue.IsFormed || !lowestValue.IsFormed)
return;
if (prevClose is not decimal pc || prevTrendEma is not decimal pt)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var fibHigh = highestValue.GetValue<decimal>();
var fibLow = lowestValue.GetValue<decimal>();
var fib236 = fibHigh - (fibHigh - fibLow) * _fibLevel;
var shortSignal = pc < fibHigh && fastValue.GetValue<decimal>() < slowValue.GetValue<decimal>();
if (Position < 0)
{
var crossAboveTrend = pc <= pt && close > trendEma;
if ((crossAboveTrend && close <= _entryPrice) || (pc > fib236 && !shortSignal))
BuyMarket(-Position);
return;
}
if (Position == 0 && shortSignal)
{
SellMarket(Volume);
_entryPrice = close;
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Decimal
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage, Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
FAST_EMA_LENGTH = 21
SLOW_EMA_LENGTH = 55
TREND_EMA_LENGTH = 200
FIB_LEVEL = 0.236
class cc_trend_2_downtrend_short_strategy(Strategy):
"""
CC Trend Strategy 2 Downtrend Short.
Short only. The Fibonacci range spans the lowest low and the highest high of the last FibLength candles, and its 0.236 level lies
23.6% of the range below the high. A short opens when the previous close is below the Fibonacci high and EMA21 is below EMA55.
It closes when the close crosses above EMA200 while the trade is not losing, or when the previous close is above the 0.236 level
and there is no new short signal.
"""
def __init__(self):
super(cc_trend_2_downtrend_short_strategy, self).__init__()
self._fib_length = self.Param("FibLength", 100).SetGreaterThanZero().SetDisplay("Fib Length", "Candles of the Fibonacci range", "Fibonacci")
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_trend_ema = None
self._entry_price = Decimal(0)
def OnReseted(self):
super(cc_trend_2_downtrend_short_strategy, self).OnReseted()
self._reset_state()
def OnStarted2(self, time):
super(cc_trend_2_downtrend_short_strategy, self).OnStarted2(time)
self._reset_state()
fast_ema = ExponentialMovingAverage()
fast_ema.Length = FAST_EMA_LENGTH
slow_ema = ExponentialMovingAverage()
slow_ema.Length = SLOW_EMA_LENGTH
trend_ema = ExponentialMovingAverage()
trend_ema.Length = TREND_EMA_LENGTH
highest = Highest()
highest.Length = self._fib_length.Value
lowest = Lowest()
lowest.Length = self._fib_length.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(fast_ema, slow_ema, trend_ema, highest, lowest, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast_ema)
self.DrawIndicator(area, slow_ema)
self.DrawIndicator(area, trend_ema)
self.DrawOwnTrades(area)
def _process_candle(self, candle, fast_value, slow_value, trend_value, highest_value, lowest_value):
if candle.State != CandleStates.Finished:
return
close = candle.ClosePrice
pc = self._prev_close
pt = self._prev_trend_ema
self._prev_close = close
if not trend_value.IsFormed:
return
trend_ema = trend_value.GetValue[Decimal](None)
self._prev_trend_ema = trend_ema
if not fast_value.IsFormed or not slow_value.IsFormed or not highest_value.IsFormed or not lowest_value.IsFormed:
return
if pc is None or pt is None:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
fib_high = highest_value.GetValue[Decimal](None)
fib_low = lowest_value.GetValue[Decimal](None)
fib236 = fib_high - (fib_high - fib_low) * Decimal(FIB_LEVEL)
short_signal = pc < fib_high and fast_value.GetValue[Decimal](None) < slow_value.GetValue[Decimal](None)
if self.Position < 0:
cross_above_trend = pc <= pt and close > trend_ema
if (cross_above_trend and close <= self._entry_price) or (pc > fib236 and not short_signal):
self.BuyMarket(-self.Position)
return
if self.Position == 0 and short_signal:
self.SellMarket(self.Volume)
self._entry_price = close
def CreateClone(self):
return cc_trend_2_downtrend_short_strategy()