Estrategia Quantum Stochastic
Esta estrategia opera utilizando el oscilador Stochastic. Cuando %K sale de la zona de sobreventa cruzando por encima de LowLevel, abre una posición larga. Cuando %K cae de la zona de sobrecompra cruzando por debajo de HighLevel, abre una posición corta. Las posiciones se cierran en umbrales extremos para capturar beneficios.
Detalles
- Criterios de entrada:
- Largo: %K cruza por encima de
LowLevel. - Corto: %K cruza por debajo de
HighLevel.
- Largo: %K cruza por encima de
- Criterios de salida:
- Largo: %K alcanza
HighCloseLevel. - Corto: %K alcanza
LowCloseLevel.
- Largo: %K alcanza
- Indicadores: Stochastic Oscillator.
- Marco temporal: Parámetro
CandleType(por defecto 1 minuto). - Parámetros:
KPeriod– período de la línea %K.DPeriod– período de la línea %D.Slowing– factor de suavizado del Stochastic.HighLevel– límite inferior de la zona de sobrecompra.LowLevel– límite superior de la zona de sobreventa.HighCloseLevel– nivel para cerrar posiciones largas.LowCloseLevel– nivel para cerrar posiciones cortas.
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>
/// Quantum Stochastic strategy based on Stochastic oscillator thresholds.
/// Buys when %K leaves oversold zone and sells when %K leaves overbought zone.
/// </summary>
public class QuantumStochasticStrategy : Strategy
{
private readonly StrategyParam<int> _kPeriod;
private readonly StrategyParam<int> _dPeriod;
private readonly StrategyParam<decimal> _highLevel;
private readonly StrategyParam<decimal> _lowLevel;
private readonly StrategyParam<DataType> _candleType;
private decimal? _previousK;
public int KPeriod
{
get => _kPeriod.Value;
set => _kPeriod.Value = value;
}
public int DPeriod
{
get => _dPeriod.Value;
set => _dPeriod.Value = value;
}
public decimal HighLevel
{
get => _highLevel.Value;
set => _highLevel.Value = value;
}
public decimal LowLevel
{
get => _lowLevel.Value;
set => _lowLevel.Value = value;
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public QuantumStochasticStrategy()
{
_kPeriod = Param(nameof(KPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("%K Period", "Period of %K line", "Stochastic");
_dPeriod = Param(nameof(DPeriod), 3)
.SetGreaterThanZero()
.SetDisplay("%D Period", "Period of %D line", "Stochastic");
_highLevel = Param(nameof(HighLevel), 80m)
.SetDisplay("High Level", "Bottom of overbought zone", "Levels");
_lowLevel = Param(nameof(LowLevel), 20m)
.SetDisplay("Low Level", "Top of oversold zone", "Levels");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_previousK = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var stochastic = new StochasticOscillator();
stochastic.K.Length = KPeriod;
stochastic.D.Length = DPeriod;
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(stochastic, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, stochastic);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue stochValue)
{
if (candle.State != CandleStates.Finished)
return;
var stoch = (IStochasticOscillatorValue)stochValue;
if (stoch.K is not decimal kValue)
return;
if (!IsFormedAndOnlineAndAllowTrading())
{
_previousK = kValue;
return;
}
if (_previousK is not decimal prevK)
{
_previousK = kValue;
return;
}
// Buy when %K crosses above oversold level
if (prevK < LowLevel && kValue >= LowLevel && Position <= 0)
BuyMarket();
// Sell when %K crosses below overbought level
if (prevK > HighLevel && kValue <= HighLevel && Position >= 0)
SellMarket();
_previousK = kValue;
}
}
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 StochasticOscillator
from StockSharp.Algo.Strategies import Strategy
class quantum_stochastic_strategy(Strategy):
def __init__(self):
super(quantum_stochastic_strategy, self).__init__()
self._k_period = self.Param("KPeriod", 14) \
.SetDisplay("%K Period", "Period of %K line", "Stochastic")
self._d_period = self.Param("DPeriod", 3) \
.SetDisplay("%D Period", "Period of %D line", "Stochastic")
self._high_level = self.Param("HighLevel", 80.0) \
.SetDisplay("High Level", "Bottom of overbought zone", "Levels")
self._low_level = self.Param("LowLevel", 20.0) \
.SetDisplay("Low Level", "Top of oversold zone", "Levels")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._previous_k = None
@property
def k_period(self):
return self._k_period.Value
@property
def d_period(self):
return self._d_period.Value
@property
def high_level(self):
return self._high_level.Value
@property
def low_level(self):
return self._low_level.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(quantum_stochastic_strategy, self).OnReseted()
self._previous_k = None
def OnStarted2(self, time):
super(quantum_stochastic_strategy, self).OnStarted2(time)
stochastic = StochasticOscillator()
stochastic.K.Length = self.k_period
stochastic.D.Length = self.d_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(stochastic, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, stochastic)
self.DrawOwnTrades(area)
def process_candle(self, candle, stoch_value):
if candle.State != CandleStates.Finished:
return
k = stoch_value.K
if k is None:
return
k_value = float(k)
if not self.IsFormedAndOnlineAndAllowTrading():
self._previous_k = k_value
return
if self._previous_k is None:
self._previous_k = k_value
return
prev_k = self._previous_k
low = float(self.low_level)
high = float(self.high_level)
# Buy when %K crosses above oversold level
if prev_k < low and k_value >= low and self.Position <= 0:
self.BuyMarket()
# Sell when %K crosses below overbought level
if prev_k > high and k_value <= high and self.Position >= 0:
self.SellMarket()
self._previous_k = k_value
def CreateClone(self):
return quantum_stochastic_strategy()