Стратегия Candels High Open
Стратегия торгует, когда свеча открывается точно на своем максимуме или минимуме. Длинная позиция открывается, если цена открытия равна минимуму свечи, ожидая роста. Короткая позиция открывается, если цена открытия равна максимуму свечи, ожидая снижения. Выход осуществляется при пересечении цены с значением Parabolic SAR, который выступает в роли трейлинг-выхода.
Подробности
- Условия входа:
- Длинная:
Open == Low - Короткая:
Open == High
- Длинная:
- Long/Short: Оба
- Условия выхода: цена пересекает Parabolic SAR или появляется противоположный сигнал
- Стопы: используется фиксированный стоп-лосс и тейк-профит
- Параметры по умолчанию:
StopLevel= 50mTakeLevel= 50mSarStep= 0.02mSarMax= 0.2mCandleType= TimeSpan.FromMinutes(5).TimeFrame()ReverseSignals= false
- Фильтры:
- Категория: ценовое действие
- Направление: оба
- Индикаторы: Parabolic SAR
- Стопы: да
- Сложность: базовая
- Таймфрейм: внутридневной
- Сезонность: нет
- Нейросети: нет
- Дивергенция: нет
- Уровень риска: средний
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy that enters when a candle opens at its high or low and exits on Parabolic SAR reversal.
/// </summary>
public class CandelsHighOpenStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<bool> _reverseSignals;
private readonly StrategyParam<decimal> _stopLevel;
private readonly StrategyParam<decimal> _takeLevel;
private readonly StrategyParam<decimal> _sarStep;
private readonly StrategyParam<decimal> _sarMax;
/// <summary>
/// Candle type for calculations.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Reverse entry signals.
/// </summary>
public bool ReverseSignals
{
get => _reverseSignals.Value;
set => _reverseSignals.Value = value;
}
/// <summary>
/// Stop loss level in absolute price.
/// </summary>
public decimal StopLevel
{
get => _stopLevel.Value;
set => _stopLevel.Value = value;
}
/// <summary>
/// Take profit level in absolute price.
/// </summary>
public decimal TakeLevel
{
get => _takeLevel.Value;
set => _takeLevel.Value = value;
}
/// <summary>
/// Parabolic SAR acceleration step.
/// </summary>
public decimal SarStep
{
get => _sarStep.Value;
set => _sarStep.Value = value;
}
/// <summary>
/// Parabolic SAR maximum acceleration.
/// </summary>
public decimal SarMax
{
get => _sarMax.Value;
set => _sarMax.Value = value;
}
/// <summary>
/// Initializes a new instance of the strategy.
/// </summary>
public CandelsHighOpenStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles used for processing", "General")
;
_reverseSignals = Param(nameof(ReverseSignals), false)
.SetDisplay("Reverse Signals", "Invert long and short signals", "General")
;
_stopLevel = Param(nameof(StopLevel), 50m)
.SetGreaterThanZero()
.SetDisplay("Stop Level", "Absolute stop loss distance", "Protection")
;
_takeLevel = Param(nameof(TakeLevel), 50m)
.SetGreaterThanZero()
.SetDisplay("Take Level", "Absolute take profit distance", "Protection")
;
_sarStep = Param(nameof(SarStep), 0.02m)
.SetGreaterThanZero()
.SetDisplay("SAR Step", "Acceleration factor step for Parabolic SAR", "Indicators")
;
_sarMax = Param(nameof(SarMax), 0.2m)
.SetGreaterThanZero()
.SetDisplay("SAR Max", "Maximum acceleration factor for Parabolic SAR", "Indicators")
;
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var psar = new ParabolicSar
{
Acceleration = SarStep,
AccelerationMax = SarMax,
AccelerationStep = SarStep
};
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(psar, ProcessCandle)
.Start();
StartProtection(
stopLoss: new Unit(StopLevel, UnitTypes.Absolute),
takeProfit: new Unit(TakeLevel, UnitTypes.Absolute));
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, psar);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal psarValue)
{
if (candle.State != CandleStates.Finished)
return;
// Exit conditions based on Parabolic SAR reversal
if (Position > 0 && candle.ClosePrice < psarValue)
{
SellMarket();
return;
}
if (Position < 0 && candle.ClosePrice > psarValue)
{
BuyMarket();
return;
}
var openAtHigh = candle.OpenPrice == candle.HighPrice;
var openAtLow = candle.OpenPrice == candle.LowPrice;
if (ReverseSignals)
{
var tmp = openAtHigh;
openAtHigh = openAtLow;
openAtLow = tmp;
}
if (openAtLow && Position <= 0)
{
BuyMarket();
}
else if (openAtHigh && Position >= 0)
{
SellMarket();
}
}
}
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, Unit, UnitTypes
from StockSharp.Algo.Indicators import ParabolicSar
from StockSharp.Algo.Strategies import Strategy
class candels_high_open_strategy(Strategy):
def __init__(self):
super(candels_high_open_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4)))
self._reverse_signals = self.Param("ReverseSignals", False)
self._stop_level = self.Param("StopLevel", 50.0)
self._take_level = self.Param("TakeLevel", 50.0)
self._sar_step = self.Param("SarStep", 0.02)
self._sar_max = self.Param("SarMax", 0.2)
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def ReverseSignals(self):
return self._reverse_signals.Value
@ReverseSignals.setter
def ReverseSignals(self, value):
self._reverse_signals.Value = value
@property
def StopLevel(self):
return self._stop_level.Value
@StopLevel.setter
def StopLevel(self, value):
self._stop_level.Value = value
@property
def TakeLevel(self):
return self._take_level.Value
@TakeLevel.setter
def TakeLevel(self, value):
self._take_level.Value = value
@property
def SarStep(self):
return self._sar_step.Value
@SarStep.setter
def SarStep(self, value):
self._sar_step.Value = value
@property
def SarMax(self):
return self._sar_max.Value
@SarMax.setter
def SarMax(self, value):
self._sar_max.Value = value
def OnStarted2(self, time):
super(candels_high_open_strategy, self).OnStarted2(time)
psar = ParabolicSar()
psar.Acceleration = self.SarStep
psar.AccelerationMax = self.SarMax
psar.AccelerationStep = self.SarStep
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(psar, self.ProcessCandle).Start()
self.StartProtection(
Unit(self.TakeLevel, UnitTypes.Absolute),
Unit(self.StopLevel, UnitTypes.Absolute))
def ProcessCandle(self, candle, psar_value):
if candle.State != CandleStates.Finished:
return
price = float(candle.ClosePrice)
psar_val = float(psar_value)
if self.Position > 0 and price < psar_val:
self.SellMarket()
return
if self.Position < 0 and price > psar_val:
self.BuyMarket()
return
open_at_high = float(candle.OpenPrice) == float(candle.HighPrice)
open_at_low = float(candle.OpenPrice) == float(candle.LowPrice)
if self.ReverseSignals:
tmp = open_at_high
open_at_high = open_at_low
open_at_low = tmp
if open_at_low and self.Position <= 0:
self.BuyMarket()
elif open_at_high and self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return candels_high_open_strategy()