Inicio
/
Ejemplos de estrategias
Ver en GitHub
Estrategia OHLC Stochastic
Estrategia de seguimiento de momentum que usa el oscilador Stochastic clásico %K/%D en velas OHLC.
El algoritmo reacciona a cruces en zonas de sobrecompra/sobreventa y protege las operaciones abiertas con un trailing stop configurable medido en pasos de precio.
Detalles
Idea principal : explotar el cambio de momentum cuando el Stochastic %K cruza %D en niveles extremos.
Criterios de entrada :
Largo :
%K cruza por encima de %D y al menos una de las líneas está por debajo del umbral LevelDown.
Si existe una posición corta, se cierra y se revierte a larga.
Corto :
%K cruza por debajo de %D y al menos una de las líneas está por encima del umbral LevelUp.
Si existe una posición larga, se cierra y se revierte a corta.
Criterios de salida :
Se activa el trailing stop (basado en la distancia TrailingStopSteps y el requisito de mejora TrailingStepSteps).
Aparece la señal de entrada opuesta, desencadenando una reversión.
Lógica de trailing :
La distancia y el paso se multiplican por el PriceStep del instrumento para convertir pips/pasos en precios absolutos.
El stop solo avanza después de que la operación se mueve más allá de TrailingStopSteps + TrailingStepSteps desde el precio de entrada.
Lógica de trailing separada para los lados largo y corto.
Indicadores :
Largo/Corto : Ambos.
Stops : Solo trailing stop (sin órdenes fijas de SL/TP).
Dimensionamiento de posición : Usa el parámetro Volume de la estrategia; las reversiones envían Volume + |Position| para cambiar de dirección.
Parámetros predeterminados :
CandleType = TimeSpan.FromHours(12).TimeFrame()
KPeriod = 5
DPeriod = 3
Slowing = 3
LevelUp = 70
LevelDown = 30
TrailingStopSteps = 5 (pasos de precio)
TrailingStepSteps = 2 (pasos de precio)
Visualización :
Dibuja velas OHLC, indicador Stochastic y marcadores de operaciones cuando hay gráficos disponibles.
Notas de uso
Configure el instrumento subyacente y el marco temporal antes de iniciar la estrategia.
Ajuste TrailingStopSteps según el tamaño del tick del instrumento para reflejar distancias reales en pips.
La estrategia llama a StartProtection() para que se puedan adjuntar reglas de riesgo adicionales externamente.
Funciona mejor en regímenes de tendencia donde las reversiones del Stochastic lideran el precio.
Para productos intradiarios, los marcos temporales más bajos pueden requerir reducir las distancias de trailing para evitar salidas prematuras.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class OhlcStochasticStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _rsiPeriod;
private decimal? _prevRsi;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int RsiPeriod { get => _rsiPeriod.Value; set => _rsiPeriod.Value = value; }
public OhlcStochasticStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
_rsiPeriod = Param(nameof(RsiPeriod), 14).SetGreaterThanZero().SetDisplay("RSI Period", "RSI lookback", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevRsi = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevRsi = null;
var rsi = new RelativeStrengthIndex { Length = RsiPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(rsi, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal rsiVal)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) { _prevRsi = rsiVal; return; }
if (_prevRsi == null) { _prevRsi = rsiVal; return; }
if (_prevRsi.Value < 30m && rsiVal >= 30m && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
else if (_prevRsi.Value > 70m && rsiVal <= 70m && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
_prevRsi = rsiVal;
}
}
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 RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class ohlc_stochastic_strategy(Strategy):
def __init__(self):
super(ohlc_stochastic_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._rsi_period = self.Param("RsiPeriod", 14) \
.SetDisplay("RSI Period", "RSI lookback", "Indicators")
self._prev_rsi = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def RsiPeriod(self):
return self._rsi_period.Value
def OnReseted(self):
super(ohlc_stochastic_strategy, self).OnReseted()
self._prev_rsi = None
def OnStarted2(self, time):
super(ohlc_stochastic_strategy, self).OnStarted2(time)
self._prev_rsi = None
rsi = RelativeStrengthIndex()
rsi.Length = self.RsiPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(rsi, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _on_process(self, candle, rsi_value):
if candle.State != CandleStates.Finished:
return
rv = float(rsi_value)
if not self.IsFormedAndOnlineAndAllowTrading():
self._prev_rsi = rv
return
if self._prev_rsi is None:
self._prev_rsi = rv
return
if self._prev_rsi < 30.0 and rv >= 30.0 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._prev_rsi > 70.0 and rv <= 70.0 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_rsi = rv
def CreateClone(self):
return ohlc_stochastic_strategy()