Estrategia MasterMind 3
Esta estrategia opera reversiones extremas usando cuatro indicadores Williams %R con diferentes períodos. Cuando todos los indicadores caen a valores profundos de sobreventa, la estrategia entra en una posición larga. Cuando todos los indicadores suben a valores fuertes de sobrecompra, entra en una posición corta.
Lógica de trading
- Suscribirse a velas del marco temporal seleccionado.
- Calcular cuatro indicadores Williams %R con períodos 26, 27, 29 y 30.
- Comprar cuando todos los indicadores estén por debajo de
-99.99.
- Vender cuando todos los indicadores estén por encima de
-0.01.
- Las señales se procesan solo en velas completadas.
El volumen de la orden se toma de la propiedad Volume de la estrategia. Las posiciones opuestas existentes se cierran automáticamente enviando una orden de mercado del tamaño requerido.
Parámetros
| Nombre |
Descripción |
Predeterminado |
WprPeriod1 |
Longitud del primer indicador Williams %R |
26 |
WprPeriod2 |
Longitud del segundo indicador Williams %R |
27 |
WprPeriod3 |
Longitud del tercer indicador Williams %R |
29 |
WprPeriod4 |
Longitud del cuarto indicador Williams %R |
30 |
CandleType |
Tipo y marco temporal de velas |
Velas de 1 minuto |
Notas
- La estrategia utiliza la API de alto nivel con
Bind para el procesamiento de indicadores.
- No incluye niveles de stop loss o take profit; la posición se invierte en señales opuestas.
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>
/// Williams %R based extreme reversals.
/// Enters long when all indicators show deep oversold.
/// Enters short when all indicators show strong overbought.
/// </summary>
public class MasterMind3Strategy : Strategy
{
private readonly StrategyParam<int> _rsiPeriod1;
private readonly StrategyParam<int> _rsiPeriod2;
private readonly StrategyParam<int> _rsiPeriod3;
private readonly StrategyParam<int> _rsiPeriod4;
private readonly StrategyParam<DataType> _candleType;
private bool _wasOversold;
private bool _wasOverbought;
/// <summary>
/// Period for the first Williams %R indicator.
/// </summary>
public int RsiPeriod1
{
get => _rsiPeriod1.Value;
set => _rsiPeriod1.Value = value;
}
/// <summary>
/// Period for the second Williams %R indicator.
/// </summary>
public int RsiPeriod2
{
get => _rsiPeriod2.Value;
set => _rsiPeriod2.Value = value;
}
/// <summary>
/// Period for the third Williams %R indicator.
/// </summary>
public int RsiPeriod3
{
get => _rsiPeriod3.Value;
set => _rsiPeriod3.Value = value;
}
/// <summary>
/// Period for the fourth Williams %R indicator.
/// </summary>
public int RsiPeriod4
{
get => _rsiPeriod4.Value;
set => _rsiPeriod4.Value = value;
}
/// <summary>
/// The type of candles to use for calculations.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes strategy parameters.
/// </summary>
public MasterMind3Strategy()
{
_rsiPeriod1 = Param(nameof(RsiPeriod1), 26)
.SetGreaterThanZero()
.SetDisplay("RSI Period 1", "Length of the first RSI indicator", "RSI")
.SetOptimize(10, 50, 5);
_rsiPeriod2 = Param(nameof(RsiPeriod2), 27)
.SetGreaterThanZero()
.SetDisplay("RSI Period 2", "Length of the second RSI indicator", "RSI")
.SetOptimize(10, 50, 5);
_rsiPeriod3 = Param(nameof(RsiPeriod3), 29)
.SetGreaterThanZero()
.SetDisplay("RSI Period 3", "Length of the third RSI indicator", "RSI")
.SetOptimize(10, 50, 5);
_rsiPeriod4 = Param(nameof(RsiPeriod4), 30)
.SetGreaterThanZero()
.SetDisplay("RSI Period 4", "Length of the fourth RSI indicator", "RSI")
.SetOptimize(10, 50, 5);
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame())
.SetDisplay("Candle Type", "Type of candles for the strategy", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_wasOversold = false;
_wasOverbought = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var rsi1 = new RelativeStrengthIndex { Length = RsiPeriod1 };
var rsi2 = new RelativeStrengthIndex { Length = RsiPeriod2 };
var rsi3 = new RelativeStrengthIndex { Length = RsiPeriod3 };
var rsi4 = new RelativeStrengthIndex { Length = RsiPeriod4 };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(rsi1, rsi2, rsi3, rsi4, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, rsi1);
DrawIndicator(area, rsi2);
DrawIndicator(area, rsi3);
DrawIndicator(area, rsi4);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal rsi1, decimal rsi2, decimal rsi3, decimal rsi4)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var isOversold = rsi1 <= 35m && rsi2 <= 35m && rsi3 <= 35m && rsi4 <= 35m;
var isOverbought = rsi1 >= 65m && rsi2 >= 65m && rsi3 >= 65m && rsi4 >= 65m;
var isBuySignal = isOversold && !_wasOversold;
var isSellSignal = isOverbought && !_wasOverbought;
if (isBuySignal && Position <= 0)
{
BuyMarket(Volume + Math.Abs(Position));
}
else if (isSellSignal && Position >= 0)
{
SellMarket(Volume + Math.Abs(Position));
}
_wasOversold = isOversold;
_wasOverbought = isOverbought;
}
}
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 RelativeStrengthIndex
from StockSharp.Algo.Strategies import Strategy
class master_mind3_strategy(Strategy):
def __init__(self):
super(master_mind3_strategy, self).__init__()
self._rsi_period1 = self.Param("RsiPeriod1", 26)
self._rsi_period2 = self.Param("RsiPeriod2", 27)
self._rsi_period3 = self.Param("RsiPeriod3", 29)
self._rsi_period4 = self.Param("RsiPeriod4", 30)
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(15)))
self._was_oversold = False
self._was_overbought = False
@property
def RsiPeriod1(self):
return self._rsi_period1.Value
@RsiPeriod1.setter
def RsiPeriod1(self, value):
self._rsi_period1.Value = value
@property
def RsiPeriod2(self):
return self._rsi_period2.Value
@RsiPeriod2.setter
def RsiPeriod2(self, value):
self._rsi_period2.Value = value
@property
def RsiPeriod3(self):
return self._rsi_period3.Value
@RsiPeriod3.setter
def RsiPeriod3(self, value):
self._rsi_period3.Value = value
@property
def RsiPeriod4(self):
return self._rsi_period4.Value
@RsiPeriod4.setter
def RsiPeriod4(self, value):
self._rsi_period4.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnStarted2(self, time):
super(master_mind3_strategy, self).OnStarted2(time)
self._was_oversold = False
self._was_overbought = False
rsi1 = RelativeStrengthIndex()
rsi1.Length = self.RsiPeriod1
rsi2 = RelativeStrengthIndex()
rsi2.Length = self.RsiPeriod2
rsi3 = RelativeStrengthIndex()
rsi3.Length = self.RsiPeriod3
rsi4 = RelativeStrengthIndex()
rsi4.Length = self.RsiPeriod4
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(rsi1, rsi2, rsi3, rsi4, self.ProcessCandle).Start()
def ProcessCandle(self, candle, rsi1_val, rsi2_val, rsi3_val, rsi4_val):
if candle.State != CandleStates.Finished:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
r1 = float(rsi1_val)
r2 = float(rsi2_val)
r3 = float(rsi3_val)
r4 = float(rsi4_val)
is_oversold = r1 <= 35.0 and r2 <= 35.0 and r3 <= 35.0 and r4 <= 35.0
is_overbought = r1 >= 65.0 and r2 >= 65.0 and r3 >= 65.0 and r4 >= 65.0
buy_signal = is_oversold and not self._was_oversold
sell_signal = is_overbought and not self._was_overbought
if buy_signal and self.Position <= 0:
self.BuyMarket()
elif sell_signal and self.Position >= 0:
self.SellMarket()
self._was_oversold = is_oversold
self._was_overbought = is_overbought
def OnReseted(self):
super(master_mind3_strategy, self).OnReseted()
self._was_oversold = False
self._was_overbought = False
def CreateClone(self):
return master_mind3_strategy()