Candels High Open Strategy
该策略在蜡烛开盘价等于其最高价或最低价时进行交易。 当开盘价等于最低价时,预期价格上行,开多仓。 当开盘价等于最高价时,预期价格下行,开空仓。 当价格穿越抛物线SAR指标时平仓,该指标作为移动退出。
细节
- 入场条件:
- 多头:
Open == Low - 空头:
Open == High
- 多头:
- 多/空: 双向
- 出场条件: 价格穿越 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()