Стратегия Long Explosive V1
Long Explosive V1 открывает длинную позицию, когда цена закрытия резко возрастает на заданный процент относительно предыдущей свечи. Позиция закрывается при падении цены на указанный процент или перед открытием нового входа.
Подробности
- Условия входа:
- Long:
Close - PrevClose > Close * Price increase (%) / 100.
- Long:
- Направление: Только лонг.
- Условия выхода:
Close - PrevClose < -Close * Price decrease (%) / 100или перед новым входом. - Стопы: Нет.
- Значения по умолчанию:
Price increase (%)= 1Price decrease (%)= 1
- Фильтры:
- Категория: Импульс
- Направление: Лонг
- Индикаторы: Цена
- Стопы: Нет
- Сложность: Низкая
- Таймфрейм: Любой
- Сезонность: Нет
- Нейросети: Нет
- Дивергенция: Нет
- Уровень риска: Низкий
using System;
using Ecng.Common;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Explosive strategy that enters positions on strong price moves.
/// Goes long on sharp increases and short on sharp decreases.
/// </summary>
public class LongExplosiveV1Strategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<decimal> _priceIncreasePercent;
private readonly StrategyParam<decimal> _priceDecreasePercent;
private readonly StrategyParam<int> _cooldownBars;
private decimal _previousClose;
private int _barsSinceSignal;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public decimal PriceIncreasePercent
{
get => _priceIncreasePercent.Value;
set => _priceIncreasePercent.Value = value;
}
public decimal PriceDecreasePercent
{
get => _priceDecreasePercent.Value;
set => _priceDecreasePercent.Value = value;
}
public int CooldownBars
{
get => _cooldownBars.Value;
set => _cooldownBars.Value = value;
}
public LongExplosiveV1Strategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
_priceIncreasePercent = Param(nameof(PriceIncreasePercent), 0.5m)
.SetDisplay("Price increase (%)", "Percentage increase to go long", "General");
_priceDecreasePercent = Param(nameof(PriceDecreasePercent), 0.5m)
.SetDisplay("Price decrease (%)", "Percentage decrease to go short", "General");
_cooldownBars = Param(nameof(CooldownBars), 20)
.SetDisplay("Cooldown Bars", "Min bars between signals", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_previousClose = 0;
_barsSinceSignal = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_previousClose = 0;
_barsSinceSignal = 0;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
_barsSinceSignal++;
if (_previousClose == 0)
{
_previousClose = candle.ClosePrice;
return;
}
var change = (candle.ClosePrice - _previousClose) / _previousClose * 100m;
_previousClose = candle.ClosePrice;
if (_barsSinceSignal < CooldownBars)
return;
// Strong increase -> go long
if (change > PriceIncreasePercent && Position <= 0)
{
BuyMarket(Volume + Math.Abs(Position));
_barsSinceSignal = 0;
}
// Strong decrease -> go short
else if (change < -PriceDecreasePercent && Position >= 0)
{
SellMarket(Volume + Math.Abs(Position));
_barsSinceSignal = 0;
}
}
}
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.Strategies import Strategy
class long_explosive_v1_strategy(Strategy):
def __init__(self):
super(long_explosive_v1_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._price_increase_percent = self.Param("PriceIncreasePercent", 0.5) \
.SetDisplay("Price increase (%)", "Percentage increase to go long", "General")
self._price_decrease_percent = self.Param("PriceDecreasePercent", 0.5) \
.SetDisplay("Price decrease (%)", "Percentage decrease to go short", "General")
self._cooldown_bars = self.Param("CooldownBars", 20) \
.SetDisplay("Cooldown Bars", "Min bars between signals", "General")
self._previous_close = 0.0
self._bars_since_signal = 0
@property
def candle_type(self):
return self._candle_type.Value
@candle_type.setter
def candle_type(self, value):
self._candle_type.Value = value
def OnReseted(self):
super(long_explosive_v1_strategy, self).OnReseted()
self._previous_close = 0.0
self._bars_since_signal = 0
def OnStarted2(self, time):
super(long_explosive_v1_strategy, self).OnStarted2(time)
self._previous_close = 0.0
self._bars_since_signal = 0
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def OnProcess(self, candle):
if candle.State != CandleStates.Finished:
return
self._bars_since_signal += 1
close = float(candle.ClosePrice)
if self._previous_close == 0.0:
self._previous_close = close
return
change = (close - self._previous_close) / self._previous_close * 100.0
self._previous_close = close
if self._bars_since_signal < self._cooldown_bars.Value:
return
inc = float(self._price_increase_percent.Value)
dec = float(self._price_decrease_percent.Value)
if change > inc and self.Position <= 0:
self.BuyMarket(self.Volume + abs(self.Position))
self._bars_since_signal = 0
elif change < -dec and self.Position >= 0:
self.SellMarket(self.Volume + abs(self.Position))
self._bars_since_signal = 0
def CreateClone(self):
return long_explosive_v1_strategy()