Стратегия RobotPower M5
Стратегия объединяет индикаторы Bulls Power и Bears Power на пятиминутном графике. Позиции открываются при переходе суммарного импульса быков и медведей через ноль, выходы выполняются по фиксированным целям и трейлинг-стопу.
Как работает
- Индикаторы: Bulls Power и Bears Power с общим периодом
BullBearPeriod. - Таймфрейм: свечи по 5 минут по умолчанию (
CandleType).
Правила входа
- Покупка: если
BullsPower + BearsPower > 0и позиции нет. - Продажа: если
BullsPower + BearsPower < 0и позиции нет.
Правила выхода
- Take Profit: позиция закрывается при движении цены на
TakeProfitединиц в сторону сделки. - Stop Loss: позиция закрывается при движении цены против сделки на
StopLossединиц. - Трейлинг-стоп: после входа стоп переносится на
TrailingStep, когда цена проходит более чем двойной размер этого шага.
Параметры
BullBearPeriod– период расчёта Bulls Power и Bears Power.TrailingStep– шаг для трейлинг-стопа.TakeProfit– расстояние от входа до уровня фиксации прибыли.StopLoss– расстояние от входа до уровня ограничения убытка.CandleType– таймфрейм свечей для расчёта сигналов.
Размер позиции
Используется свойство Volume стратегии.
Примечание
Пример конвертации стратегии из MQL в API 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()