SHE Kanskigor Strategy
This daily strategy opens a single position each day based on the direction of the previous day's candle. At the configured time it buys if the prior day closed below its open and sells if it closed above. A fixed take-profit and stop-loss measured in price steps manage risk. Only one trade is allowed per day.
Details
- Entry Criteria: At
StartTimecompare the previous day's open and close; buy whenopen > close, sell whenopen < close - Long/Short: Both
- Exit Criteria: take profit or stop loss
- Stops: Yes
- Default Values:
Volume= 0.1StartTime= 00:05TakeProfit= 350StopLoss= 550
- Filters:
- Category: Reversal
- Direction: Both
- Indicators: None
- Stops: Yes
- Complexity: Basic
- Timeframe: Daily
- Seasonality: No
- Neural networks: No
- Divergence: No
- Risk level: Medium
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>
/// Strategy that trades based on consecutive same-direction candles with EMA filter.
/// </summary>
public class SheKanskigorStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevOpen;
private decimal _prevClose;
private decimal _prevPrevOpen;
private decimal _prevPrevClose;
private int _candleCount;
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public SheKanskigorStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevOpen = 0;
_prevClose = 0;
_prevPrevOpen = 0;
_prevPrevClose = 0;
_candleCount = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
SubscribeCandles(CandleType).Bind(ema, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal emaValue)
{
if (candle.State != CandleStates.Finished) return;
_candleCount++;
if (_candleCount < 3)
{
_prevPrevOpen = _prevOpen;
_prevPrevClose = _prevClose;
_prevOpen = candle.OpenPrice;
_prevClose = candle.ClosePrice;
return;
}
// Two consecutive bearish candles -> buy reversal (with EMA confirmation)
var twoBearish = _prevPrevOpen > _prevPrevClose && _prevOpen > _prevClose;
// Two consecutive bullish candles -> sell reversal
var twoBullish = _prevPrevOpen < _prevPrevClose && _prevOpen < _prevClose;
if (twoBearish && candle.ClosePrice > emaValue && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (twoBullish && candle.ClosePrice < emaValue && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevPrevOpen = _prevOpen;
_prevPrevClose = _prevClose;
_prevOpen = candle.OpenPrice;
_prevClose = candle.ClosePrice;
}
}
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 she_kanskigor_strategy(Strategy):
def __init__(self):
super(she_kanskigor_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 20) \
.SetDisplay("EMA Period", "EMA period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle type", "General")
self._prev_open = 0.0
self._prev_close = 0.0
self._prev_prev_open = 0.0
self._prev_prev_close = 0.0
self._candle_count = 0
@property
def ema_period(self):
return self._ema_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(she_kanskigor_strategy, self).OnReseted()
self._prev_open = 0.0
self._prev_close = 0.0
self._prev_prev_open = 0.0
self._prev_prev_close = 0.0
self._candle_count = 0
def OnStarted2(self, time):
super(she_kanskigor_strategy, self).OnStarted2(time)
ema = ExponentialMovingAverage()
ema.Length = self.ema_period
self.SubscribeCandles(self.candle_type).Bind(ema, self.process_candle).Start()
def process_candle(self, candle, ema_value):
if candle.State != CandleStates.Finished:
return
self._candle_count += 1
if self._candle_count < 3:
self._prev_prev_open = self._prev_open
self._prev_prev_close = self._prev_close
self._prev_open = float(candle.OpenPrice)
self._prev_close = float(candle.ClosePrice)
return
ev = float(ema_value)
close = float(candle.ClosePrice)
two_bearish = self._prev_prev_open > self._prev_prev_close and self._prev_open > self._prev_close
two_bullish = self._prev_prev_open < self._prev_prev_close and self._prev_open < self._prev_close
if two_bearish and close > ev and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif two_bullish and close < ev and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_prev_open = self._prev_open
self._prev_prev_close = self._prev_close
self._prev_open = float(candle.OpenPrice)
self._prev_close = float(candle.ClosePrice)
def CreateClone(self):
return she_kanskigor_strategy()