Estrategia RobotPower M5
Esta estrategia combina los indicadores Bulls Power y Bears Power en un gráfico de 5 minutos.
Abre posiciones cuando el impulso combinado de toros y osos cruza cero y gestiona las salidas con objetivos fijos y un trailing stop.
Cómo funciona
- Indicadores: Bulls Power y Bears Power con un período compartido
BullBearPeriod.
- Marco temporal: velas de 5 minutos por defecto (
CandleType).
Reglas de entrada
- Entrada larga: Cuando
BullsPower + BearsPower > 0 y no hay posición abierta, comprar a mercado.
- Entrada corta: Cuando
BullsPower + BearsPower < 0 y no hay posición abierta, vender a mercado.
Reglas de salida
- Take Profit: Cerrar la posición cuando el precio se mueve
TakeProfit unidades en la dirección de la operación.
- Stop Loss: Cerrar la posición si el precio se mueve contra la posición
StopLoss unidades.
- Trailing Stop: Después de la entrada, el stop loss sigue al precio por
TrailingStep una vez que el precio avanza más del doble de esa distancia.
Parámetros
BullBearPeriod – período para los cálculos de Bulls Power y Bears Power.
TrailingStep – tamaño del paso al ajustar el trailing stop.
TakeProfit – distancia desde la entrada hasta el nivel de take profit.
StopLoss – distancia desde la entrada hasta el nivel de stop loss.
CandleType – marco temporal de las velas para el cálculo de señales.
Tamaño de posición
Utiliza la propiedad Volume de la estrategia para el tamaño de la orden.
Notas
Diseñada con fines educativos y sirve como ejemplo de conversión de una estrategia MQL a la API de StockSharp.
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>
/// Bulls and Bears Power crossover strategy with trailing stop.
/// Buys when Bulls Power plus Bears Power is positive and sells when negative.
/// Applies fixed take profit and stop loss with trailing adjustment.
/// </summary>
public class RobotPowerM5Strategy : Strategy
{
private readonly StrategyParam<int> _bullBearPeriod;
private readonly StrategyParam<decimal> _trailingStep;
private readonly StrategyParam<decimal> _takeProfit;
private readonly StrategyParam<decimal> _stopLoss;
private readonly StrategyParam<DataType> _candleType;
private decimal _stopPrice;
private decimal _takePrice;
/// <summary>
/// Period for Bulls Power and Bears Power.
/// </summary>
public int BullBearPeriod
{
get => _bullBearPeriod.Value;
set => _bullBearPeriod.Value = value;
}
/// <summary>
/// Trailing step distance.
/// </summary>
public decimal TrailingStep
{
get => _trailingStep.Value;
set => _trailingStep.Value = value;
}
/// <summary>
/// Take profit distance in price units.
/// </summary>
public decimal TakeProfit
{
get => _takeProfit.Value;
set => _takeProfit.Value = value;
}
/// <summary>
/// Stop loss distance in price units.
/// </summary>
public decimal StopLoss
{
get => _stopLoss.Value;
set => _stopLoss.Value = value;
}
/// <summary>
/// Candle type used for calculations.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes a new instance of <see cref="RobotPowerM5Strategy"/>.
/// </summary>
public RobotPowerM5Strategy()
{
_bullBearPeriod = Param(nameof(BullBearPeriod), 5)
.SetGreaterThanZero()
.SetDisplay("Bull/Bear Period", "Bulls and Bears Power period", "Indicators");
_trailingStep = Param(nameof(TrailingStep), 10m)
.SetGreaterThanZero()
.SetDisplay("Trailing Step", "Trailing stop step size", "Risk");
_takeProfit = Param(nameof(TakeProfit), 150m)
.SetGreaterThanZero()
.SetDisplay("Take Profit", "Take profit distance", "Risk");
_stopLoss = Param(nameof(StopLoss), 105m)
.SetGreaterThanZero()
.SetDisplay("Stop Loss", "Stop loss distance", "Risk");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_stopPrice = 0m;
_takePrice = 0m;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_stopPrice = 0m;
_takePrice = 0m;
var bulls = new BullPower { Length = BullBearPeriod };
var bears = new BearPower { Length = BullBearPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(bulls, bears, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, bulls);
DrawIndicator(area, bears);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal bullsValue, decimal bearsValue)
{
if (candle.State != CandleStates.Finished)
return;
var sum = bullsValue + bearsValue;
if (Position == 0)
{
if (sum > 0)
{
BuyMarket();
_stopPrice = candle.ClosePrice - StopLoss;
_takePrice = candle.ClosePrice + TakeProfit;
}
else if (sum < 0)
{
SellMarket();
_stopPrice = candle.ClosePrice + StopLoss;
_takePrice = candle.ClosePrice - TakeProfit;
}
return;
}
if (Position > 0)
{
if (candle.LowPrice <= _stopPrice || candle.HighPrice >= _takePrice)
{
SellMarket();
_stopPrice = 0m;
_takePrice = 0m;
return;
}
if (candle.ClosePrice - _stopPrice > 2 * TrailingStep)
_stopPrice = candle.ClosePrice - TrailingStep;
}
else if (Position < 0)
{
if (candle.HighPrice >= _stopPrice || candle.LowPrice <= _takePrice)
{
BuyMarket();
_stopPrice = 0m;
_takePrice = 0m;
return;
}
if (_stopPrice - candle.ClosePrice > 2 * TrailingStep)
_stopPrice = candle.ClosePrice + TrailingStep;
}
}
}
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 BullPower, BearPower
from StockSharp.Algo.Strategies import Strategy
class robot_power_m5_strategy(Strategy):
def __init__(self):
super(robot_power_m5_strategy, self).__init__()
self._bb_period = self.Param("BullBearPeriod", 5).SetGreaterThanZero().SetDisplay("Bull/Bear Period", "Bulls and Bears Power period", "Indicators")
self._trailing_step = self.Param("TrailingStep", 10.0).SetGreaterThanZero().SetDisplay("Trailing Step", "Trailing stop step", "Risk")
self._tp = self.Param("TakeProfit", 150.0).SetGreaterThanZero().SetDisplay("Take Profit", "TP distance", "Risk")
self._sl = self.Param("StopLoss", 105.0).SetGreaterThanZero().SetDisplay("Stop Loss", "SL distance", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))).SetDisplay("Candle Type", "Candle timeframe", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(robot_power_m5_strategy, self).OnReseted()
self._stop_price = 0
self._take_price = 0
def OnStarted2(self, time):
super(robot_power_m5_strategy, self).OnStarted2(time)
self._stop_price = 0
self._take_price = 0
bulls = BullPower()
bulls.Length = self._bb_period.Value
bears = BearPower()
bears.Length = self._bb_period.Value
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(bulls, bears, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawIndicator(area, bulls)
self.DrawIndicator(area, bears)
self.DrawOwnTrades(area)
def OnProcess(self, candle, bulls_val, bears_val):
if candle.State != CandleStates.Finished:
return
total = bulls_val + bears_val
close = candle.ClosePrice
if self.Position == 0:
if total > 0:
self.BuyMarket()
self._stop_price = close - self._sl.Value
self._take_price = close + self._tp.Value
elif total < 0:
self.SellMarket()
self._stop_price = close + self._sl.Value
self._take_price = close - self._tp.Value
return
if self.Position > 0:
if candle.LowPrice <= self._stop_price or candle.HighPrice >= self._take_price:
self.SellMarket()
self._stop_price = 0
self._take_price = 0
return
if close - self._stop_price > 2 * self._trailing_step.Value:
self._stop_price = close - self._trailing_step.Value
elif self.Position < 0:
if candle.HighPrice >= self._stop_price or candle.LowPrice <= self._take_price:
self.BuyMarket()
self._stop_price = 0
self._take_price = 0
return
if self._stop_price - close > 2 * self._trailing_step.Value:
self._stop_price = close + self._trailing_step.Value
def CreateClone(self):
return robot_power_m5_strategy()